[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / tools / llvm-shlib / gen-msvc-exports.py
blob5ecb8c2da3476816c9a1e0691ed4331cb73c4bbc
1 # ===- gen-msvc-exports.py - Generate C API export file -------*- python -*--===#
3 # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 # See https://llvm.org/LICENSE.txt for license information.
5 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 # ===------------------------------------------------------------------------===#
9 # Generate an export file from a list of given LIB files. This only exports symbols
10 # that start with LLVM, so it only exports the LLVM C API.
12 # To have CMake run this, set LLVM_BUILD_LLVM_C_DYLIB to on while
13 # building on Windows.
15 # To run manually, build LLVM with Visual Studio, use a Command prompt
16 # to navigate to the directory with the .lib files (Debug\lib etc). Then run
17 # python C:\Path\To\gen-msvc-exports.py --nm ..\bin\llvm-nm.exe LLVM*.lib
19 # If you're generating a 32 bit DLL, use the `--underscore` flag.
20 # If you want to use a different `llvm-nm` executable, pass the path
21 # with the `--nm` flag.
23 # You can use the --output flag to set the name of the export file.
25 # ===------------------------------------------------------------------------===#
26 from tempfile import mkstemp
27 from contextlib import contextmanager
28 from subprocess import check_call
29 import argparse
30 import os
31 import re
34 _UNDERSCORE_REGEX = {
35 False: re.compile(r"^\w+\s+T\s+(LLVM.*)$"),
36 True: re.compile(r"^\w+\s+T\s+_(LLVM.*)$"),
40 @contextmanager
41 def removing(path):
42 try:
43 yield path
44 finally:
45 os.unlink(path)
48 def touch_tempfile(*args, **kwargs):
49 fd, name = mkstemp(*args, **kwargs)
50 os.close(fd)
51 return name
54 def gen_llvm_c_export(output, underscore, libs, nm):
55 """Generate the export file for the LLVM-C DLL.
57 Run `nm` for each lib in `libs`, and output an export file
58 to `output`. If `underscore` is true, symbols will
59 be assumed to be prefixed with an underscore.
60 """
61 with removing(touch_tempfile(prefix="dumpout", suffix=".txt")) as dumpout:
63 # Get the right regex.
64 p = _UNDERSCORE_REGEX[underscore]
66 with open(output, "w+t") as output_f:
68 # For each lib get the LLVM* functions it exports.
69 for lib in libs:
70 # Call dumpbin.
71 with open(dumpout, "w+t") as dumpout_f:
72 check_call([nm, "-g", lib], stdout=dumpout_f)
74 # Get the matching lines.
75 with open(dumpout) as dumpbin:
76 for line in dumpbin:
77 m = p.match(line)
78 if m is not None:
79 output_f.write(m.group(1) + "\n")
82 def main():
83 parser = argparse.ArgumentParser("gen-msvc-exports")
85 parser.add_argument(
86 "-i",
87 "--libsfile",
88 help="file with list of libs, new line separated",
89 action="store",
90 default=None,
92 parser.add_argument(
93 "-o", "--output", help="output filename", default="LLVM-C.exports"
95 parser.add_argument(
96 "-u",
97 "--underscore",
98 help="labels are prefixed with an underscore (use for 32 bit DLLs)",
99 action="store_true",
101 parser.add_argument(
102 "--nm", help="path to the llvm-nm executable", default="llvm-nm"
104 parser.add_argument(
105 "libs",
106 metavar="LIBS",
107 nargs="*",
108 help="list of libraries to generate export from",
111 ns = parser.parse_args()
113 libs = ns.libs
115 # Add if we where given a libsfile add it to the libs.
116 if ns.libsfile:
117 with open(ns.libsfile) as f:
118 libs.extend(f.read().splitlines())
120 gen_llvm_c_export(ns.output, ns.underscore, libs, ns.nm)
123 if __name__ == "__main__":
124 main()