1#! /usr/bin/env python3 2"""nm2def.py 3 4Helpers to extract symbols from Unix libs and auto-generate 5Windows definition files from them. Depends on nm(1). Tested 6on Linux and Solaris only (-p option to nm is for Solaris only). 7 8By Marc-Andre Lemburg, Aug 1998. 9 10Additional notes: the output of nm is supposed to look like this: 11 12acceler.o: 13000001fd T PyGrammar_AddAccelerators 14 U PyGrammar_FindDFA 1500000237 T PyGrammar_RemoveAccelerators 16 U _IO_stderr_ 17 U exit 18 U fprintf 19 U free 20 U malloc 21 U printf 22 23grammar1.o: 2400000000 T PyGrammar_FindDFA 2500000034 T PyGrammar_LabelRepr 26 U _PyParser_TokenNames 27 U abort 28 U printf 29 U sprintf 30 31... 32 33Even if this isn't the default output of your nm, there is generally an 34option to produce this format (since it is the original v7 Unix format). 35 36""" 37import os, sys 38 39PYTHONLIB = 'libpython%d.%d.a' % sys.version_info[:2] 40PC_PYTHONLIB = 'Python%d%d.dll' % sys.version_info[:2] 41NM = 'nm -p -g %s' # For Linux, use "nm -g %s" 42 43def symbols(lib=PYTHONLIB,types=('T','C','D')): 44 45 with os.popen(NM % lib) as pipe: 46 lines = pipe.readlines() 47 lines = [s.strip() for s in lines] 48 symbols = {} 49 for line in lines: 50 if len(line) == 0 or ':' in line: 51 continue 52 items = line.split() 53 if len(items) != 3: 54 continue 55 address, type, name = items 56 if type not in types: 57 continue 58 symbols[name] = address,type 59 return symbols 60 61def export_list(symbols): 62 63 data = [] 64 code = [] 65 for name,(addr,type) in symbols.items(): 66 if type in ('C','D'): 67 data.append('\t'+name) 68 else: 69 code.append('\t'+name) 70 data.sort() 71 data.append('') 72 code.sort() 73 return ' DATA\n'.join(data)+'\n'+'\n'.join(code) 74 75# Definition file template 76DEF_TEMPLATE = """\ 77EXPORTS 78%s 79""" 80 81# Special symbols that have to be included even though they don't 82# pass the filter 83SPECIALS = ( 84 ) 85 86def filter_Python(symbols,specials=SPECIALS): 87 88 for name in list(symbols.keys()): 89 if name[:2] == 'Py' or name[:3] == '_Py': 90 pass 91 elif name not in specials: 92 del symbols[name] 93 94def main(): 95 96 s = symbols(PYTHONLIB) 97 filter_Python(s) 98 exports = export_list(s) 99 f = sys.stdout # open('PC/python_nt.def','w') 100 f.write(DEF_TEMPLATE % (exports)) 101 # f.close() 102 103if __name__ == '__main__': 104 main() 105