Home | History | Annotate | Download | only in scripts
      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