117 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
| #===- gen-msvc-exports.py - Generate C API export file -------*- python -*--===#
 | |
| #
 | |
| # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| # See https://llvm.org/LICENSE.txt for license information.
 | |
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| #
 | |
| #===------------------------------------------------------------------------===#
 | |
| #
 | |
| # Generate an export file from a list of given LIB files. This only exports symbols
 | |
| # that start with LLVM, so it only exports the LLVM C API.
 | |
| #
 | |
| # To have CMake run this, set LLVM_BUILD_LLVM_C_DYLIB to on while
 | |
| # building on Windows.
 | |
| #
 | |
| # To run manually, build LLVM with Visual Studio, use a Command prompt
 | |
| # to navigate to the directory with the .lib files (Debug\lib etc). Then run
 | |
| #     python C:\Path\To\gen-msvc-exports.py --nm ..\bin\llvm-nm.exe LLVM*.lib
 | |
| #
 | |
| # If you're generating a 32 bit DLL, use the `--underscore` flag.
 | |
| # If you want to use a different `llvm-nm` executable, pass the path
 | |
| # with the `--nm` flag.
 | |
| #
 | |
| # You can use the --output flag to set the name of the export file.
 | |
| #
 | |
| #===------------------------------------------------------------------------===#
 | |
| from tempfile import mkstemp
 | |
| from contextlib import contextmanager
 | |
| from subprocess import check_call
 | |
| import argparse
 | |
| import os
 | |
| import re
 | |
| 
 | |
| 
 | |
| _UNDERSCORE_REGEX = {
 | |
|     False: re.compile(r"^\w+\s+T\s+(LLVM.*)$"),
 | |
|     True:  re.compile(r"^\w+\s+T\s+_(LLVM.*)$")
 | |
| }
 | |
| 
 | |
| 
 | |
| @contextmanager
 | |
| def removing(path):
 | |
|     try:
 | |
|         yield path
 | |
|     finally:
 | |
|         os.unlink(path)
 | |
| 
 | |
| 
 | |
| def touch_tempfile(*args, **kwargs):
 | |
|     fd, name = mkstemp(*args, **kwargs)
 | |
|     os.close(fd)
 | |
|     return name
 | |
| 
 | |
| 
 | |
| def gen_llvm_c_export(output, underscore, libs, nm):
 | |
|     """Generate the export file for the LLVM-C DLL.
 | |
| 
 | |
|     Run `nm` for each lib in `libs`, and output an export file
 | |
|     to `output`. If `underscore` is true, symbols will
 | |
|     be assumed to be prefixed with an underscore.
 | |
|     """
 | |
|     with removing(touch_tempfile(prefix='dumpout', suffix='.txt')) as dumpout:
 | |
| 
 | |
|         # Get the right regex.
 | |
|         p = _UNDERSCORE_REGEX[underscore]
 | |
| 
 | |
|         with open(output, 'w+t') as output_f:
 | |
| 
 | |
|             # For each lib get the LLVM* functions it exports.
 | |
|             for lib in libs:
 | |
|                 # Call dumpbin.
 | |
|                 with open(dumpout, 'w+t') as dumpout_f:
 | |
|                     check_call([nm, '-g', lib], stdout=dumpout_f)
 | |
| 
 | |
|                 # Get the matching lines.
 | |
|                 with open(dumpout) as dumpbin:
 | |
|                     for line in dumpbin:
 | |
|                         m = p.match(line)
 | |
|                         if m is not None:
 | |
|                             output_f.write(m.group(1) + '\n')
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     parser = argparse.ArgumentParser('gen-msvc-exports')
 | |
| 
 | |
|     parser.add_argument(
 | |
|         '-i', '--libsfile', help='file with list of libs, new line separated',
 | |
|         action='store', default=None
 | |
|     )
 | |
|     parser.add_argument(
 | |
|         '-o', '--output', help='output filename', default='LLVM-C.exports'
 | |
|     )
 | |
|     parser.add_argument('-u', '--underscore',
 | |
|         help='labels are prefixed with an underscore (use for 32 bit DLLs)',
 | |
|         action='store_true'
 | |
|     )
 | |
|     parser.add_argument(
 | |
|         '--nm', help='path to the llvm-nm executable', default='llvm-nm'
 | |
|     )
 | |
|     parser.add_argument(
 | |
|         'libs', metavar='LIBS', nargs='*', help='list of libraries to generate export from'
 | |
|     )
 | |
| 
 | |
|     ns = parser.parse_args()
 | |
| 
 | |
|     libs = ns.libs
 | |
| 
 | |
|     # Add if we where given a libsfile add it to the libs.
 | |
|     if ns.libsfile:
 | |
|         with open(ns.libsfile) as f:
 | |
|             libs.extend(f.read().splitlines())
 | |
| 
 | |
|     gen_llvm_c_export(ns.output, ns.underscore, libs, ns.nm)
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     main()
 |