Changeset 496

Show
Ignore:
Timestamp:
Fri Jul 25 05:35:06 2008
Author:
htgoebel
Message:

Code cleanup: Put tests/checks into function to enhance readability.

Files:

Legend:

Unmodified
Added
Removed
Modified
  • trunk/Configure.py

    r495 r496  
    34 34 HOME = os.path.dirname(sys.argv[0])  
    35 35  
    36   from optparse import OptionParser  
    37   parser = OptionParser(usage="%prog [options] <executable_or_dynamic_library>")  
    38   parser.add_option('--target-platform', default=None,  
    39                     help='Target platform, required for cross-bundling (default: current platform).')  
    40   parser.add_option('--executable', default=None,  
    41                     help='Python executable to use. Required for cross-bundling.')  
    42    
    43   opts, args = parser.parse_args()  
    44   if args:  
    45       parser.error('Does not expect any arguments')  
    46    
    47   configfile = os.path.join(HOME, 'config.dat')  
    48   try:  
    49       config = eval(open(configfile, 'r').read())  
    50   except IOError, SyntaxError:  
    51       # IOerror: file not present  
    52       # SyntaxError: invalid file (platform change?)  
    53       config = {'useELFEXE':1}    # if not set by Make.py we can assume Windows  
    54    
    55   # Save Python version, to detect and avoid conflicts  
    56   config["pythonVersion"] = sys.version  
    57    
    58 36 iswin = sys.platform[:3] == 'win'  
    59 37 is24 = hasattr(sys, "version_info") and sys.version_info[:2] >= (2,4)  
    60 38 cygwin = sys.platform == 'cygwin'  
    61 39  
    62   # EXE_dependencies  
    63   print "I: computing EXE_dependencies"  
    64   python = opts.executable or config.get('python') or sys.executable  
    65   target_platform = opts.target_platform or config.get('target_platform') or sys.platform  
    66   config['python'] = python  
    67   config['target_platform'] = target_platform  
    68   target_iswin = target_platform[:3] == 'win'  
    69    
    70   if not iswin:  
    71       while os.path.islink(python):  
    72           python = os.path.join(os.path.split(python)[0], os.readlink(python))  
    73    
    74   xtrapath = []  
    75   if target_iswin and not iswin:  
    76       # try to find a mounted Windows system  
    77       xtrapath = glob.glob('/mnt/*/WINDOWS/system32/')  
    78       if not xtrapath:  
    79           print "E: Can not find a mounted Windows system"  
    80           print "W: Please set 'xtrpath' in the config file yourself"  
    81    
    82   xtrapath = config.get('xtrapath') or xtrapath  
    83   config['xtrapath'] = xtrapath  
    84    
    85   toc = bindepend.Dependencies([('', python, '')], target_platform, xtrapath)  
    86    
    87   if iswin and sys.version[:3] == '1.5':  
    88       import exceptions  
    89       toc.append((os.path.basename(exceptions.__file__), exceptions.__file__, 'BINARY'))  
    90   config['EXE_dependencies'] = toc[1:]  
      40  
      41 def find_EXE_dependencies(config):  
      42     global target_platform, target_iswin  
      43     print "I: computing EXE_dependencies"  
      44     python = opts.executable or config.get('python') or sys.executable  
      45     target_platform = opts.target_platform or config.get('target_platform') or sys.platform  
      46     config['python'] = python  
      47     config['target_platform'] = target_platform  
      48     target_iswin = target_platform[:3] == 'win'  
      49  
      50     if not iswin:  
      51         while os.path.islink(python):  
      52             python = os.path.join(os.path.split(python)[0], os.readlink(python))  
      53  
      54     xtrapath = []  
      55     if target_iswin and not iswin:  
      56         # try to find a mounted Windows system  
      57         xtrapath = glob.glob('/mnt/*/WINDOWS/system32/')  
      58         if not xtrapath:  
      59             print "E: Can not find a mounted Windows system"  
      60             print "W: Please set 'xtrpath' in the config file yourself"  
      61  
      62     xtrapath = config.get('xtrapath') or xtrapath  
      63     config['xtrapath'] = xtrapath  
      64  
      65     toc = bindepend.Dependencies([('', python, '')], target_platform, xtrapath)  
      66  
      67     if iswin and sys.version[:3] == '1.5':  
      68         import exceptions  
      69         toc.append((os.path.basename(exceptions.__file__), exceptions.__file__, 'BINARY'))  
      70     config['EXE_dependencies'] = toc[1:]  
      71  
    91 72  
    92 73 _useTK = """\  
     
    106 87 """  
    107 88  
    108   # TCL_root, TK_root and support/useTK.py  
    109   print "I: Finding TCL/TK..."  
    110   if not (target_iswin):  
    111       saveexcludes = bindepend.excludes  
    112       bindepend.excludes = {}  
    113   pattern = [r'libtcl(\d\.\d)?\.so', r'(?i)tcl(\d\d)\.dll'][target_iswin]  
    114   a = mf.ImportTracker()  
    115   a.analyze_r('Tkinter')  
    116   binaries = []  
    117   for modnm, mod in a.modules.items():  
    118       if isinstance(mod, mf.ExtensionModule):  
    119           binaries.append((mod.__name__, mod.__file__, 'EXTENSION'))  
    120   binaries.extend(bindepend.Dependencies(binaries))  
    121   binaries.extend(bindepend.Dependencies([('', sys.executable, '')]))  
    122   for nm, fnm, typ in binaries:  
    123       mo = re.match(pattern, nm)  
    124       if mo:  
    125           ver = mo.group(1)  
    126           tclbindir = os.path.dirname(fnm)  
    127           if target_iswin:  
    128               ver = ver[0] + '.' + ver[1:]  
    129           elif ver is None:  
    130               # we found "libtcl.so.0" so we need to get the version from the lib directory  
    131               for name in os.listdir(tclbindir):  
    132                   mo = re.match(r'tcl(\d.\d)', name)  
    133                   if mo:  
    134                       ver = mo.group(1)  
    135           print "I: found TCL/TK version %s" % ver  
    136           open(os.path.join(HOME, 'support', 'useTK.py'), 'w').write(_useTK % (ver, ver))  
    137           tclnm = 'tcl%s' % ver  
    138           tknm = 'tk%s' % ver  
    139           # Linux: /usr/lib with the .tcl files in /usr/lib/tcl8.3 and /usr/lib/tk8.3  
    140           # Windows: Python21/DLLs with the .tcl files in Python21/tcl/tcl8.3 and Python21/tcl/tk8.3  
    141           #      or  D:/Programs/Tcl/bin with the .tcl files in D:/Programs/Tcl/lib/tcl8.0 and D:/Programs/Tcl/lib/tk8.0  
    142           if target_iswin:  
    143               for attempt in ['../tcl', '../lib']:  
    144                   if os.path.exists(os.path.join(tclbindir, attempt, tclnm)):  
    145                       config['TCL_root'] = os.path.join(tclbindir, attempt, tclnm)  
    146                       config['TK_root'] = os.path.join(tclbindir, attempt, tknm)  
    147                       break  
    148           else:  
    149               config['TCL_root'] = os.path.join(tclbindir, tclnm)  
    150               config['TK_root'] = os.path.join(tclbindir, tknm)  
    151           break  
    152   else:  
    153       print "I: could not find TCL/TK"  
    154   if not target_iswin:  
    155       bindepend.excludes = saveexcludes  
      89 def test_TCL_TK(config):  
      90     # TCL_root, TK_root and support/useTK.py  
      91     print "I: Finding TCL/TK..."  
      92     if not (target_iswin):  
      93         saveexcludes = bindepend.excludes  
      94         bindepend.excludes = {}  
      95     pattern = [r'libtcl(\d\.\d)?\.so', r'(?i)tcl(\d\d)\.dll'][target_iswin]  
      96     a = mf.ImportTracker()  
      97     a.analyze_r('Tkinter')  
      98     binaries = []  
      99     for modnm, mod in a.modules.items():  
      100         if isinstance(mod, mf.ExtensionModule):  
      101             binaries.append((mod.__name__, mod.__file__, 'EXTENSION'))  
      102     binaries.extend(bindepend.Dependencies(binaries))  
      103     binaries.extend(bindepend.Dependencies([('', sys.executable, '')]))  
      104     for nm, fnm, typ in binaries:  
      105         mo = re.match(pattern, nm)  
      106         if mo:  
      107             ver = mo.group(1)  
      108             tclbindir = os.path.dirname(fnm)  
      109             if target_iswin:  
      110                 ver = ver[0] + '.' + ver[1:]  
      111             elif ver is None:  
      112                 # we found "libtcl.so.0" so we need to get the version from the lib directory  
      113                 for name in os.listdir(tclbindir):  
      114                     mo = re.match(r'tcl(\d.\d)', name)  
      115                     if mo:  
      116                         ver = mo.group(1)  
      117             print "I: found TCL/TK version %s" % ver  
      118             open(os.path.join(HOME, 'support', 'useTK.py'), 'w').write(_useTK % (ver, ver))  
      119             tclnm = 'tcl%s' % ver  
      120             tknm = 'tk%s' % ver  
      121             # Linux: /usr/lib with the .tcl files in /usr/lib/tcl8.3 and /usr/lib/tk8.3  
      122             # Windows: Python21/DLLs with the .tcl files in Python21/tcl/tcl8.3 and Python21/tcl/tk8.3  
      123             #      or  D:/Programs/Tcl/bin with the .tcl files in D:/Programs/Tcl/lib/tcl8.0 and D:/Programs/Tcl/lib/tk8.0  
      124             if target_iswin:  
      125                 for attempt in ['../tcl', '../lib']:  
      126                     if os.path.exists(os.path.join(tclbindir, attempt, tclnm)):  
      127                         config['TCL_root'] = os.path.join(tclbindir, attempt, tclnm)  
      128                         config['TK_root'] = os.path.join(tclbindir, attempt, tknm)  
      129                         break  
      130             else:  
      131                 config['TCL_root'] = os.path.join(tclbindir, tclnm)  
      132                 config['TK_root'] = os.path.join(tclbindir, tknm)  
      133             break  
      134     else:  
      135         print "I: could not find TCL/TK"  
      136     if not target_iswin:  
      137         bindepend.excludes = saveexcludes  
    156 138  
    157   #useZLIB  
    158   print "I: testing for Zlib..."  
    159   try:  
    160       import zlib  
    161   except ImportError:  
    162       config['useZLIB'] = 0  
    163       print 'I: ... Zlib unavailable'  
    164   else:  
    165       config['useZLIB'] = 1  
    166       print 'I: ... Zlib available'  
    167 139  
    168   #hasRsrcUpdate  
    169   if iswin:  
      140 def test_Zlib(config):  
      141     #useZLIB  
      142     print "I: testing for Zlib..."  
      143     try:  
      144         import zlib  
      145         config['useZLIB'] = 1  
      146         print 'I: ... Zlib available'  
      147     except ImportError:  
      148         config['useZLIB'] = 0  
      149         print 'I: ... Zlib unavailable'  
      150  
      151 def test_RsrcUpdate(config):  
      152     config['hasRsrcUpdate'] = 0  
      153     if not iswin:  
      154         return  
    170 155     # only available on windows  
    171 156     print "I: Testing for ability to set icons, version resources..."  
     
    173 158         import win32api, icon, versionInfo  
    174 159     except ImportError, detail:  
    175           config['hasRsrcUpdate'] = 0  
    176 160         print 'I: ... resource update unavailable -', detail  
      161         return  
      162      
      163     test_exe = os.path.join(HOME, 'support', 'loader', 'run_7rw.exe')  
      164     if not os.path.exists( test_exe ):  
      165         config['hasRsrcUpdate'] = 0  
      166         print 'E: ... resource update unavailable - %s not found' % test_exe  
      167         return  
      168  
      169     # The test_exe may be read-only  
      170     # make a writable copy and test using that  
      171     rw_test_exe = os.path.join( os.environ['TEMP'], 'me_test_exe.tmp' )  
      172     shutil.copyfile( test_exe, rw_test_exe )  
      173     try:  
      174         hexe = win32api.BeginUpdateResource(rw_test_exe, 0)  
      175     except:  
      176         print 'I: ... resource update unavailable - win32api.BeginUpdateResource failed'  
    177 177     else:  
    178           test_exe = os.path.join(HOME, 'support', 'loader', 'run_7rw.exe')  
    179           if not os.path.exists( test_exe ):  
    180               config['hasRsrcUpdate'] = 0  
    181               print 'E: ... resource update unavailable - %s not found' % test_exe  
    182           else:  
    183               # The test_exe may be read-only  
    184               # make a writable copy and test using that  
    185               rw_test_exe = os.path.join( os.environ['TEMP'], 'me_test_exe.tmp' )  
    186               shutil.copyfile( test_exe, rw_test_exe )  
    187               try:  
    188                   hexe = win32api.BeginUpdateResource(rw_test_exe,0)  
    189               except:  
    190                   config['hasRsrcUpdate'] = 0  
    191                   print 'I: ... resource update unavailable - win32api.BeginUpdateResource failed'  
    192               else:  
    193                   win32api.EndUpdateResource(hexe, 1)  
    194                   config['hasRsrcUpdate'] = 1  
    195                   print 'I: ... resource update available'  
    196               os.remove(rw_test_exe)  
    197   else:  
    198       config['hasRsrcUpdate'] = 0  
      178         win32api.EndUpdateResource(hexe, 1)  
      179         config['hasRsrcUpdate'] = 1  
      180         print 'I: ... resource update available'  
      181     os.remove(rw_test_exe)  
      182  
    199 183  
    200 184 _useUnicode = """\  
     
    206 190 _useUnicodeFN = os.path.join(HOME, 'support', 'useUnicode.py')  
    207 191  
    208   #hasUnicode  
    209   print 'I: Testing for Unicode support...'  
    210   try:  
    211       import codecs  
    212       config['hasUnicode'] = 1  
      192 def test_unicode(config):  
      193     print 'I: Testing for Unicode support...'  
    213 194     try:  
    214           import encodings  
      195         import codecs  
      196         config['hasUnicode'] = 1  
      197         try:  
      198             import encodings  
      199         except ImportError:  
      200             module = "codecs"  
      201         else:  
      202             module = "encodings"  
      203         open(_useUnicodeFN, 'w').write(_useUnicode % module)  
      204         print 'I: ... Unicode available'  
    215 205     except ImportError:  
    216           module = "codecs"  
    217       else:  
    218           module = "encodings"  
    219       open(_useUnicodeFN, 'w').write(_useUnicode % module)  
    220       print 'I: ... Unicode available'  
    221   except ImportError:  
      206         try:  
      207             os.remove(_useUnicodeFN)  
      208         except OSError:  
      209             pass  
      210         config['hasUnicode'] = 0  
      211         print 'I: ... Unicode NOT available'  
      212  
      213 def test_UPX(config):  
      214     print 'I: testing for UPX...'  
      215     hasUPX = 0  
    222 216     try:  
    223           os.remove(_useUnicodeFN)  
    224       except OSError:  
    225           pass  
    226       config['hasUnicode'] = 0  
    227       print 'I: ... Unicode NOT available'  
    228    
    229   #hasUPX  
    230   print 'I: testing for UPX...'  
    231   hasUPX = 0  
      217         vers = os.popen("upx -V").readlines()  
      218         if vers:  
      219             v = string.split(vers[0])[1]  
      220             hasUPX = tuple(map(int, string.split(v, ".")))  
      221             if iswin and is24 and hasUPX < (1,92):  
      222                 print 'E: UPX is too old! Python 2.4 under Windows requires UPX 1.92+'  
      223                 hasUPX = 0  
      224         print 'I: ...UPX %s' % (('unavailable','available')[hasUPX != 0])  
      225     except Exception, e:  
      226         print 'I: ...exception result in testing for UPX'  
      227         print e, e.args  
      228     config['hasUPX'] = hasUPX  
      229  
      230  
      231 def find_PYZ_dependencies(config):  
      232     print "I: computing PYZ dependencies..."  
      233     a = mf.ImportTracker([os.path.join(HOME, 'support')])  
      234     a.analyze_r('archive')  
      235     mod = a.modules['archive']  
      236     toc = Build.TOC([(mod.__name__, mod.__file__, 'PYMODULE')])  
      237     for i in range(len(toc)):  
      238         nm, fnm, typ = toc[i]  
      239         mod = a.modules[nm]  
      240         tmp = []  
      241         for importednm, isdelayed, isconditional in mod.imports:  
      242             if not isconditional:  
      243                 realnms = a.analyze_one(importednm, nm)  
      244                 for realnm in realnms:  
      245                     imported = a.modules[realnm]  
      246                     if not isinstance(imported, mf.BuiltinModule):  
      247                         tmp.append((imported.__name__, imported.__file__, imported.typ))  
      248         toc.extend(tmp)  
      249     toc.reverse()  
      250     config['PYZ_dependencies'] = toc.data  
      251  
      252  
      253  
      254 from optparse import OptionParser  
      255 parser = OptionParser(usage="%prog [options] <executable_or_dynamic_library>")  
      256 parser.add_option('--target-platform', default=None,  
      257                   help='Target platform, required for cross-bundling (default: current platform).')  
      258 parser.add_option('--executable', default=None,  
      259                   help='Python executable to use. Required for cross-bundling.')  
      260  
      261 opts, args = parser.parse_args()  
      262 if args:  
      263     parser.error('Does not expect any arguments')  
      264  
      265 configfile = os.path.join(HOME, 'config.dat')  
    232 266 try:  
    233       vers = os.popen("upx -V").readlines()  
    234       if not vers:  
    235           hasUPX = 0  
    236       else:  
    237           v = string.split(vers[0])[1]  
    238           hasUPX = tuple(map(int, string.split(v, ".")))  
    239           if iswin and is24 and hasUPX < (1,92):  
    240               print 'E: UPX is too old! Python 2.4 under Windows requires UPX 1.92+'  
    241               hasUPX = 0  
    242       print 'I: ...UPX %s' % (('unavailable','available')[hasUPX != 0])  
    243   except Exception, e:  
    244       print 'I: ...exception result in testing for UPX'  
    245       print e, e.args  
    246   config['hasUPX'] = hasUPX  
    247    
    248   # PYZ_dependencies  
    249   print "I: computing PYZ dependencies..."  
    250   a = mf.ImportTracker([os.path.join(HOME, 'support')])  
    251   a.analyze_r('archive')  
    252   mod = a.modules['archive']  
    253   toc = Build.TOC([(mod.__name__, mod.__file__, 'PYMODULE')])  
    254   for i in range(len(toc)):  
    255       nm, fnm, typ = toc[i]  
    256       mod = a.modules[nm]  
    257       tmp = []  
    258       for importednm, isdelayed, isconditional in mod.imports:  
    259           if not isconditional:  
    260               realnms = a.analyze_one(importednm, nm)  
    261               for realnm in realnms:  
    262                   imported = a.modules[realnm]  
    263                   if not isinstance(imported, mf.BuiltinModule):  
    264                       tmp.append((imported.__name__, imported.__file__, imported.typ))  
    265       toc.extend(tmp)  
    266   toc.reverse()  
    267   config['PYZ_dependencies'] = toc.data  
      267     config = eval(open(configfile, 'r').read())  
      268 except IOError, SyntaxError:  
      269     # IOerror: file not present  
      270     # SyntaxError: invalid file (platform change?)  
      271     config = {'useELFEXE':1}    # if not set by Make.py we can assume Windows  
      272  
      273 # Save Python version, to detect and avoid conflicts  
      274 config["pythonVersion"] = sys.version  
      275  
      276 find_EXE_dependencies(config)  
      277 test_TCL_TK(config)  
      278 test_Zlib(config)  
      279 test_RsrcUpdate(config)  
      280 test_unicode(config)  
      281 test_UPX(config)  
      282 find_PYZ_dependencies(config)  
    268 283  
    269 284 Build._save_data(configfile, config)