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):
with removing(touch_tempfile(prefix='dumpout', suffix='.txt')) as dumpout:
p = _UNDERSCORE_REGEX[underscore]
with open(output, 'w+t') as output_f:
for lib in libs:
with open(dumpout, 'w+t') as dumpout_f:
check_call([nm, '-g', lib], stdout=dumpout_f)
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
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()