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 lines = os.popen(NM % lib).readlines() 46 lines = [s.strip() for s in lines] 47 symbols = {} 48 for line in lines: 49 if len(line) == 0 or ':' in line: 50 continue 51 items = line.split() 52 if len(items) != 3: 53 continue 54 address, type, name = items 55 if type not in types: 56 continue 57 symbols[name] = address,type 58 return symbols 59 60def export_list(symbols): 61 62 data = [] 63 code = [] 64 for name,(addr,type) in symbols.items(): 65 if type in ('C','D'): 66 data.append('\t'+name) 67 else: 68 code.append('\t'+name) 69 data.sort() 70 data.append('') 71 code.sort() 72 return ' DATA\n'.join(data)+'\n'+'\n'.join(code) 73 74# Definition file template 75DEF_TEMPLATE = """\ 76EXPORTS 77%s 78""" 79 80# Special symbols that have to be included even though they don't 81# pass the filter 82SPECIALS = ( 83 ) 84 85def filter_Python(symbols,specials=SPECIALS): 86 87 for name in list(symbols.keys()): 88 if name[:2] == 'Py' or name[:3] == '_Py': 89 pass 90 elif name not in specials: 91 del symbols[name] 92 93def main(): 94 95 s = symbols(PYTHONLIB) 96 filter_Python(s) 97 exports = export_list(s) 98 f = sys.stdout # open('PC/python_nt.def','w') 99 f.write(DEF_TEMPLATE % (exports)) 100 f.close() 101 102if __name__ == '__main__': 103 main() 104