1 #! /usr/bin/env python 2 """nm2def.py 3 4 Helpers to extract symbols from Unix libs and auto-generate 5 Windows definition files from them. Depends on nm(1). Tested 6 on Linux and Solaris only (-p option to nm is for Solaris only). 7 8 By Marc-Andre Lemburg, Aug 1998. 9 10 Additional notes: the output of nm is supposed to look like this: 11 12 acceler.o: 13 000001fd T PyGrammar_AddAccelerators 14 U PyGrammar_FindDFA 15 00000237 T PyGrammar_RemoveAccelerators 16 U _IO_stderr_ 17 U exit 18 U fprintf 19 U free 20 U malloc 21 U printf 22 23 grammar1.o: 24 00000000 T PyGrammar_FindDFA 25 00000034 T PyGrammar_LabelRepr 26 U _PyParser_TokenNames 27 U abort 28 U printf 29 U sprintf 30 31 ... 32 33 Even if this isn't the default output of your nm, there is generally an 34 option to produce this format (since it is the original v7 Unix format). 35 36 """ 37 import os, sys 38 39 PYTHONLIB = 'libpython'+sys.version[:3]+'.a' 40 PC_PYTHONLIB = 'Python'+sys.version[0]+sys.version[2]+'.dll' 41 NM = 'nm -p -g %s' # For Linux, use "nm -g %s" 42 43 def 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 60 def 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 75 DEF_TEMPLATE = """\ 76 EXPORTS 77 %s 78 """ 79 80 # Special symbols that have to be included even though they don't 81 # pass the filter 82 SPECIALS = ( 83 ) 84 85 def filter_Python(symbols,specials=SPECIALS): 86 87 for name in symbols.keys(): 88 if name[:2] == 'Py' or name[:3] == '_Py': 89 pass 90 elif name not in specials: 91 del symbols[name] 92 93 def 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 102 if __name__ == '__main__': 103 main() 104