]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/config.py
ad0a8a261a05d53b7e30459743c1aabb95aa9ba2
   1 #---------------------------------------------------------------------- 
   2 # Name:        wx.build.config 
   3 # Purpose:     Most of the contents of this module used to be located  
   4 #              in wxPython's setup.py script.  It was moved here so 
   5 #              it would be installed with the rest of wxPython and 
   6 #              could therefore be used by the setup.py for other 
   7 #              projects that needed this same info and functionality 
   8 #              (most likely in order to be compatible with wxPython.) 
  10 #              This split from setup.py is still fairly rough, and 
  11 #              some things may still get shuffled back and forth, 
  12 #              refactored, etc.  Please send me any comments and 
  13 #              suggestions about this. 
  17 # Created:     23-March-2004 
  19 # Copyright:   (c) 2004 by Total Control Software 
  20 # Licence:     wxWindows license 
  21 #---------------------------------------------------------------------- 
  23 import sys
, os
, glob
, fnmatch
, tempfile
 
  24 from distutils
.core      
import setup
, Extension
 
  25 from distutils
.file_util 
import copy_file
 
  26 from distutils
.dir_util  
import mkpath
 
  27 from distutils
.dep_util  
import newer
 
  28 from distutils
.spawn     
import spawn
 
  30 import distutils
.command
.install_data
 
  31 import distutils
.command
.install_headers
 
  32 import distutils
.command
.clean
 
  34 #---------------------------------------------------------------------- 
  35 # flags and values that affect this script 
  36 #---------------------------------------------------------------------- 
  38 VER_MAJOR        
= 2      # The first three must match wxWidgets 
  41 VER_SUBREL       
= 8      # wxPython release num for x.y.z release of wxWidgets 
  42 VER_FLAGS        
= ""     # release flags, such as prerelease num, unicode, etc. 
  44 DESCRIPTION      
= "Cross platform GUI toolkit for Python" 
  46 AUTHOR_EMAIL     
= "Robin Dunn <robin@alldunn.com>" 
  47 URL              
= "http://wxPython.org/" 
  48 DOWNLOAD_URL     
= "http://wxPython.org/download.php" 
  49 LICENSE          
= "wxWidgets Library License (LGPL derivative)" 
  50 PLATFORMS        
= "WIN32,OSX,POSIX" 
  51 KEYWORDS         
= "GUI,wx,wxWindows,wxWidgets,cross-platform" 
  53 LONG_DESCRIPTION 
= """\ 
  54 wxPython is a GUI toolkit for Python that is a wrapper around the 
  55 wxWidgets C++ GUI library.  wxPython provides a large variety of 
  56 window types and controls, all implemented with a native look and 
  57 feel (by using the native widgets) on the platforms it is supported 
  62 Development Status :: 6 - Mature 
  63 Environment :: MacOS X :: Carbon 
  64 Environment :: Win32 (MS Windows) 
  65 Environment :: X11 Applications :: GTK 
  66 Intended Audience :: Developers 
  67 License :: OSI Approved 
  68 Operating System :: MacOS :: MacOS X 
  69 Operating System :: Microsoft :: Windows :: Windows 95/98/2000 
  70 Operating System :: POSIX 
  71 Programming Language :: Python 
  72 Topic :: Software Development :: User Interfaces 
  75 ## License :: OSI Approved :: wxWidgets Library Licence 
  78 # Config values below this point can be reset on the setup.py command line. 
  80 BUILD_GLCANVAS 
= 1 # If true, build the contrib/glcanvas extension module 
  81 BUILD_OGL 
= 1      # If true, build the contrib/ogl extension module 
  82 BUILD_STC 
= 1      # If true, build the contrib/stc extension module 
  83 BUILD_XRC 
= 1      # XML based resource system 
  84 BUILD_GIZMOS 
= 1   # Build a module for the gizmos contrib library 
  85 BUILD_DLLWIDGET 
= 0# Build a module that enables unknown wx widgets 
  86                    # to be loaded from a DLL and to be used from Python. 
  88                    # Internet Explorer wrapper (experimental) 
  89 BUILD_IEWIN 
= (os
.name 
== 'nt') 
  90 BUILD_ACTIVEX 
= (os
.name 
== 'nt')  # new version of IEWIN and more 
  93 CORE_ONLY 
= 0      # if true, don't build any of the above 
  95 PREP_ONLY 
= 0      # Only run the prepatory steps, not the actual build. 
  97 USE_SWIG 
= 0       # Should we actually execute SWIG, or just use the 
  98                    # files already in the distribution? 
 100 SWIG 
= "swig"      # The swig executable to use. 
 102 BUILD_RENAMERS 
= 1 # Should we build the renamer modules too? 
 104 FULL_DOCS 
= 0      # Some docstrings are split into a basic docstring and a 
 105                    # details string.  Setting this flag to 1 will 
 106                    # cause the two strings to be combined and output 
 107                    # as the full docstring. 
 109 UNICODE 
= 0        # This will pass the 'wxUSE_UNICODE' flag to SWIG and 
 110                    # will ensure that the right headers are found and the 
 111                    # right libs are linked. 
 113 UNDEF_NDEBUG 
= 1   # Python 2.2 on Unix/Linux by default defines NDEBUG, 
 114                    # and distutils will pick this up and use it on the 
 115                    # compile command-line for the extensions.  This could 
 116                    # conflict with how wxWidgets was built.  If NDEBUG is 
 117                    # set then wxWidgets' __WXDEBUG__ setting will be turned 
 118                    # off.  If wxWidgets was actually built with it turned 
 119                    # on then you end up with mismatched class structures, 
 120                    # and wxPython will crash. 
 122 NO_SCRIPTS 
= 0     # Don't install the tool scripts 
 123 NO_HEADERS 
= 0     # Don't install the wxPython *.h and *.i files 
 125 WX_CONFIG 
= None   # Usually you shouldn't need to touch this, but you can set 
 126                    # it to pass an alternate version of wx-config or alternate 
 127                    # flags, eg. as required by the .deb in-tree build.  By 
 128                    # default a wx-config command will be assembled based on 
 129                    # version, port, etc. and it will be looked for on the 
 132 WXPORT 
= 'gtk2'    # On Linux/Unix there are several ports of wxWidgets available. 
 133                    # Setting this value lets you select which will be used for 
 134                    # the wxPython build.  Possibilites are 'gtk', 'gtk2' and 
 135                    # 'x11'.  Curently only gtk and gtk2 works. 
 137 BUILD_BASE 
= "build" # Directory to use for temporary build files. 
 138                      # This name will be appended to if the WXPORT or 
 139                      # the UNICODE flags are set to non-standard 
 143 CONTRIBS_INC 
= ""  # A dir to add as an -I flag when compiling the contribs 
 146 # Some MSW build settings 
 148 FINAL 
= 0          # Mirrors use of same flag in wx makefiles, 
 149                    # (0 or 1 only) should probably find a way to 
 152 HYBRID 
= 1         # If set and not debug or FINAL, then build a 
 153                    # hybrid extension that can be used by the 
 154                    # non-debug version of python, but contains 
 155                    # debugging symbols for wxWidgets and wxPython. 
 156                    # wxWidgets must have been built with /MD, not /MDd 
 157                    # (using FINAL=hybrid will do it.) 
 159                    # Version part of wxWidgets LIB/DLL names 
 160 WXDLLVER 
= '%d%d' % (VER_MAJOR
, VER_MINOR
) 
 162 WXPY_SRC 
= '.'  # Assume we're in the source tree already, but allow the 
 163                 # user to change it, particularly for extension building. 
 166 #---------------------------------------------------------------------- 
 169     if hasattr(sys
, 'setup_is_main') and sys
.setup_is_main
: 
 174     path 
= os
.path
.join(*args
) 
 175     return os
.path
.normpath(path
) 
 190 #---------------------------------------------------------------------- 
 192 #---------------------------------------------------------------------- 
 199 force 
= '--force' in sys
.argv 
or '-f' in sys
.argv
 
 200 debug 
= '--debug' in sys
.argv 
or '-g' in sys
.argv
 
 201 cleaning 
= 'clean' in sys
.argv
 
 204 # change the PORT default for wxMac 
 205 if sys
.platform
[:6] == "darwin": 
 208 # and do the same for wxMSW, just for consistency 
 213 #---------------------------------------------------------------------- 
 214 # Check for build flags on the command line 
 215 #---------------------------------------------------------------------- 
 217 # Boolean (int) flags 
 218 for flag 
in ['BUILD_GLCANVAS', 'BUILD_OGL', 'BUILD_STC', 'BUILD_XRC', 
 219              'BUILD_GIZMOS', 'BUILD_DLLWIDGET', 'BUILD_IEWIN', 'BUILD_ACTIVEX', 
 220              'CORE_ONLY', 'PREP_ONLY', 'USE_SWIG', 'UNICODE', 
 221              'UNDEF_NDEBUG', 'NO_SCRIPTS', 'NO_HEADERS', 'BUILD_RENAMERS', 
 223              'FINAL', 'HYBRID', ]: 
 224     for x 
in range(len(sys
.argv
)): 
 225         if sys
.argv
[x
].find(flag
) == 0: 
 226             pos 
= sys
.argv
[x
].find('=') + 1 
 228                 vars()[flag
] = eval(sys
.argv
[x
][pos
:]) 
 232 for option 
in ['WX_CONFIG', 'WXDLLVER', 'BUILD_BASE', 'WXPORT', 'SWIG', 
 233                'CONTRIBS_INC', 'WXPY_SRC']: 
 234     for x 
in range(len(sys
.argv
)): 
 235         if sys
.argv
[x
].find(option
) == 0: 
 236             pos 
= sys
.argv
[x
].find('=') + 1 
 238                 vars()[option
] = sys
.argv
[x
][pos
:] 
 241 sys
.argv 
= filter(None, sys
.argv
) 
 244 #---------------------------------------------------------------------- 
 245 # some helper functions 
 246 #---------------------------------------------------------------------- 
 248 def Verify_WX_CONFIG(): 
 249     """ Called below for the builds that need wx-config, if WX_CONFIG 
 250         is not set then determins the flags needed based on build 
 251         options and searches for wx-config on the PATH.   
 253     # if WX_CONFIG hasn't been set to an explicit value then construct one. 
 255     if WX_CONFIG 
is None: 
 256         WX_CONFIG
='wx-config' 
 260         flags 
=  ' --toolkit=%s' % port
 
 261         flags 
+= ' --unicode=%s' % (UNICODE 
and 'yes' or 'no') 
 262         flags 
+= ' --version=%s.%s' % (VER_MAJOR
, VER_MINOR
) 
 264         searchpath 
= os
.environ
["PATH"] 
 265         for p 
in searchpath
.split(':'): 
 266             fp 
= os
.path
.join(p
, 'wx-config') 
 267             if os
.path
.exists(fp
) and os
.access(fp
, os
.X_OK
): 
 269                 msg("Found wx-config: " + fp
) 
 270                 msg("    Using flags: " + flags
) 
 271                 WX_CONFIG 
= fp 
+ flags
 
 274             msg("ERROR: WX_CONFIG not specified and wx-config not found on the $PATH") 
 277         # TODO:  exeucte WX_CONFIG --list and verify a matching config is found 
 280 def run_swig(files
, dir, gendir
, package
, USE_SWIG
, force
, swig_args
, 
 281              swig_deps
=[], add_under
=False): 
 282     """Run SWIG the way I want it done""" 
 284     if USE_SWIG 
and not os
.path
.exists(os
.path
.join(dir, gendir
)): 
 285         os
.mkdir(os
.path
.join(dir, gendir
)) 
 287     if USE_SWIG 
and not os
.path
.exists(os
.path
.join("docs", "xml-raw")): 
 288         if not os
.path
.exists("docs"): 
 290         os
.mkdir(os
.path
.join("docs", "xml-raw")) 
 294     if add_under
:  pre 
= '_' 
 298         basefile 
= os
.path
.splitext(file)[0] 
 299         i_file   
= os
.path
.join(dir, file) 
 300         py_file  
= os
.path
.join(dir, gendir
, pre
+basefile
+'.py') 
 301         cpp_file 
= os
.path
.join(dir, gendir
, pre
+basefile
+'_wrap.cpp') 
 302         xml_file 
= os
.path
.join("docs", "xml-raw", basefile
+pre
+'_swig.xml') 
 305             interface 
= ['-interface', '_'+basefile
+'_'] 
 309         sources
.append(cpp_file
) 
 311         if not cleaning 
and USE_SWIG
: 
 312             for dep 
in swig_deps
: 
 313                 if newer(dep
, py_file
) or newer(dep
, cpp_file
): 
 317             if force 
or newer(i_file
, py_file
) or newer(i_file
, cpp_file
): 
 318                 ## we need forward slashes here even on win32 
 319                 #cpp_file = opj(cpp_file) #'/'.join(cpp_file.split('\\')) 
 320                 #i_file = opj(i_file)     #'/'.join(i_file.split('\\')) 
 323                     xmltemp 
= tempfile
.mktemp('.xml') 
 325                     # First run swig to produce the XML file, adding 
 326                     # an extra -D that prevents the old rename 
 327                     # directives from being used 
 328                     cmd 
= [ swig_cmd 
] + swig_args 
+ \
 
 329                           [ '-DBUILDING_RENAMERS', '-xmlout', xmltemp 
] + \
 
 330                           ['-I'+dir, '-o', cpp_file
, i_file
] 
 334                     # Next run build_renamers to process the XML 
 335                     myRenamer 
= BuildRenamers() 
 336                     myRenamer
.run(dir, pre
+basefile
, xmltemp
) 
 339                 # Then run swig for real 
 340                 cmd 
= [ swig_cmd 
] + swig_args 
+ interface 
+ \
 
 341                       ['-I'+dir, '-o', cpp_file
, '-xmlout', xml_file
, i_file
] 
 346         # copy the generated python file to the package directory 
 347         copy_file(py_file
, package
, update
=not force
, verbose
=0) 
 348         CLEANUP
.append(opj(package
, os
.path
.basename(py_file
))) 
 354 # Specializations of some distutils command classes 
 355 class wx_smart_install_data(distutils
.command
.install_data
.install_data
): 
 356     """need to change self.install_dir to the actual library dir""" 
 358         install_cmd 
= self
.get_finalized_command('install') 
 359         self
.install_dir 
= getattr(install_cmd
, 'install_lib') 
 360         return distutils
.command
.install_data
.install_data
.run(self
) 
 363 class wx_extra_clean(distutils
.command
.clean
.clean
): 
 365     Also cleans stuff that this setup.py copies itself.  If the 
 366     --all flag was used also searches for .pyc, .pyd, .so files 
 369         from distutils 
import log
 
 370         from distutils
.filelist 
import FileList
 
 373         distutils
.command
.clean
.clean
.run(self
) 
 377             fl
.include_pattern("*.pyc", 0) 
 378             fl
.include_pattern("*.pyd", 0) 
 379             fl
.include_pattern("*.so", 0) 
 385                     if not self
.dry_run 
and os
.path
.exists(f
): 
 387                     log
.info("removing '%s'", f
) 
 389                     log
.warning("unable to remove '%s'", f
) 
 393                     if not self
.dry_run 
and os
.path
.exists(f
): 
 395                     log
.info("removing '%s'", f
) 
 397                     log
.warning("unable to remove '%s'", f
) 
 401 class wx_install_headers(distutils
.command
.install_headers
.install_headers
): 
 403     Install the header files to the WXPREFIX, with an extra dir per 
 406     def initialize_options (self
): 
 408         distutils
.command
.install_headers
.install_headers
.initialize_options(self
) 
 410     def finalize_options (self
): 
 411         self
.set_undefined_options('install', ('root', 'root')) 
 412         distutils
.command
.install_headers
.install_headers
.finalize_options(self
) 
 417         headers 
= self
.distribution
.headers
 
 422         if root 
is None or WXPREFIX
.startswith(root
): 
 424         for header
, location 
in headers
: 
 425             install_dir 
= os
.path
.normpath(root 
+ 
 427                                            '/include/wx-%d.%d/wx' % (VER_MAJOR
, VER_MINOR
) + 
 429             self
.mkpath(install_dir
) 
 430             (out
, _
) = self
.copy_file(header
, install_dir
) 
 431             self
.outfiles
.append(out
) 
 436 def build_locale_dir(destdir
, verbose
=1): 
 437     """Build a locale dir under the wxPython package for MSW""" 
 438     moFiles 
= glob
.glob(opj(WXDIR
, 'locale', '*.mo')) 
 440         lang 
= os
.path
.splitext(os
.path
.basename(src
))[0] 
 441         dest 
= opj(destdir
, lang
, 'LC_MESSAGES') 
 442         mkpath(dest
, verbose
=verbose
) 
 443         copy_file(src
, opj(dest
, 'wxstd.mo'), update
=1, verbose
=verbose
) 
 444         CLEANUP
.append(opj(dest
, 'wxstd.mo')) 
 448 def build_locale_list(srcdir
): 
 449     # get a list of all files under the srcdir, to be used for install_data 
 450     def walk_helper(lst
, dirname
, files
): 
 452             filename 
= opj(dirname
, f
) 
 453             if not os
.path
.isdir(filename
): 
 454                 lst
.append( (dirname
, [filename
]) ) 
 456     os
.path
.walk(srcdir
, walk_helper
, file_list
) 
 460 def find_data_files(srcdir
, *wildcards
): 
 461     # get a list of all files under the srcdir matching wildcards, 
 462     # returned in a format to be used for install_data 
 464     def walk_helper(arg
, dirname
, files
): 
 469                 filename 
= opj(dirname
, f
) 
 470                 if fnmatch
.fnmatch(filename
, wc
) and not os
.path
.isdir(filename
): 
 471                     names
.append(filename
) 
 473             lst
.append( (dirname
, names 
) ) 
 476     os
.path
.walk(srcdir
, walk_helper
, (file_list
, wildcards
)) 
 480 def makeLibName(name
): 
 481     if os
.name 
== 'posix': 
 482         libname 
= '%s_%s-%s' % (WXBASENAME
, name
, WXRELEASE
) 
 484         libname 
= 'wxmsw%s%s_%s' % (WXDLLVER
, libFlag(), name
) 
 490 def adjustCFLAGS(cflags
, defines
, includes
): 
 491     '''Extrace the raw -I, -D, and -U flags and put them into 
 492        defines and includes as needed.''' 
 496             includes
.append(flag
[2:]) 
 497         elif flag
[:2] == '-D': 
 499             if flag
.find('=') == -1: 
 500                 defines
.append( (flag
, None) ) 
 502                 defines
.append( tuple(flag
.split('=')) ) 
 503         elif flag
[:2] == '-U': 
 504             defines
.append( (flag
[2:], ) ) 
 506             newCFLAGS
.append(flag
) 
 511 def adjustLFLAGS(lfags
, libdirs
, libs
): 
 512     '''Extrace the -L and -l flags and put them in libdirs and libs as needed''' 
 516             libdirs
.append(flag
[2:]) 
 517         elif flag
[:2] == '-l': 
 518             libs
.append(flag
[2:]) 
 520             newLFLAGS
.append(flag
) 
 524 #---------------------------------------------------------------------- 
 544 if UNICODE 
and WXPORT 
not in ['msw', 'gtk2']: 
 545     raise SystemExit, "UNICODE mode not currently supported on this WXPORT: "+WXPORT
 
 549     CONTRIBS_INC 
= [ CONTRIBS_INC 
] 
 554 #---------------------------------------------------------------------- 
 555 # Setup some platform specific stuff 
 556 #---------------------------------------------------------------------- 
 559     # Set compile flags and such for MSVC.  These values are derived 
 560     # from the wxWidgets makefiles for MSVC, other compilers settings 
 561     # will probably vary... 
 562     if os
.environ
.has_key('WXWIN'): 
 563         WXDIR 
= os
.environ
['WXWIN'] 
 565         msg("WARNING: WXWIN not set in environment.") 
 566         WXDIR 
= '..'  # assumes in CVS tree 
 570     includes 
= ['include', 'src', 
 571                 opj(WXDIR
, 'lib', 'vc_dll', 'msw'  + libFlag()), 
 572                 opj(WXDIR
, 'include'), 
 573                 opj(WXDIR
, 'contrib', 'include'), 
 576     defines 
= [ ('WIN32', None), 
 582                 ('SWIG_GLOBAL', None), 
 583                 ('WXP_USE_THREAD', '1'), 
 587         defines
.append( ('NDEBUG',) )  # using a 1-tuple makes it do an undef 
 590         defines
.append( ('__NO_VC_CRTDBG__', None) ) 
 592     if not FINAL 
or HYBRID
: 
 593         defines
.append( ('__WXDEBUG__', None) ) 
 595     libdirs 
= [ opj(WXDIR
, 'lib', 'vc_dll') ] 
 596     libs 
= [ 'wxbase' + WXDLLVER 
+ libFlag(),  # TODO: trim this down to what is really needed for the core 
 597              'wxbase' + WXDLLVER 
+ libFlag() + '_net', 
 598              'wxbase' + WXDLLVER 
+ libFlag() + '_xml', 
 599              makeLibName('core')[0], 
 600              makeLibName('adv')[0], 
 601              makeLibName('html')[0], 
 604     libs 
= libs 
+ ['kernel32', 'user32', 'gdi32', 'comdlg32', 
 605             'winspool', 'winmm', 'shell32', 'oldnames', 'comctl32', 
 606             'odbc32', 'ole32', 'oleaut32', 'uuid', 'rpcrt4', 
 607             'advapi32', 'wsock32'] 
 611              # '/GX-'  # workaround for internal compiler error in MSVC on some machines 
 615     # Other MSVC flags... 
 616     # Too bad I don't remember why I was playing with these, can they be removed? 
 618         pass #cflags = cflags + ['/O1'] 
 620         pass #cflags = cflags + ['/Ox'] 
 622         pass # cflags = cflags + ['/Od', '/Z7'] 
 623              # lflags = ['/DEBUG', ] 
 627 #---------------------------------------------------------------------- 
 629 elif os
.name 
== 'posix': 
 631     includes 
= ['include', 'src'] 
 632     defines 
= [('SWIG_GLOBAL', None), 
 633                ('HAVE_CONFIG_H', None), 
 634                ('WXP_USE_THREAD', '1'), 
 637         defines
.append( ('NDEBUG',) )  # using a 1-tuple makes it do an undef 
 644     # If you get unresolved symbol errors on Solaris and are using gcc, then 
 645     # uncomment this block to add the right flags to the link step and build 
 647     ## if os.uname()[0] == 'SunOS': 
 648     ##     libs.append('gcc') 
 649     ##     libdirs.append(commands.getoutput("gcc -print-search-dirs | grep '^install' | awk '{print $2}'")[:-1]) 
 651     cflags 
= os
.popen(WX_CONFIG 
+ ' --cxxflags', 'r').read()[:-1] 
 652     cflags 
= cflags
.split() 
 659     lflags 
= os
.popen(WX_CONFIG 
+ ' --libs', 'r').read()[:-1] 
 660     lflags 
= lflags
.split() 
 662     WXBASENAME 
= os
.popen(WX_CONFIG 
+ ' --basename').read()[:-1] 
 663     WXRELEASE  
= os
.popen(WX_CONFIG 
+ ' --release').read()[:-1] 
 664     WXPREFIX   
= os
.popen(WX_CONFIG 
+ ' --prefix').read()[:-1] 
 667     if sys
.platform
[:6] == "darwin": 
 668         # Flags and such for a Darwin (Max OS X) build of Python 
 676         # Set flags for other Unix type platforms 
 681             portcfg 
= os
.popen('gtk-config --cflags', 'r').read()[:-1] 
 682         elif WXPORT 
== 'gtk2': 
 684             GENDIR 
= 'gtk' # no code differences so use the same generated sources 
 685             portcfg 
= os
.popen('pkg-config gtk+-2.0 --cflags', 'r').read()[:-1] 
 686             BUILD_BASE 
= BUILD_BASE 
+ '-' + WXPORT
 
 687         elif WXPORT 
== 'x11': 
 690             BUILD_BASE 
= BUILD_BASE 
+ '-' + WXPORT
 
 692             raise SystemExit, "Unknown WXPORT value: " + WXPORT
 
 694         cflags 
+= portcfg
.split() 
 696         # Some distros (e.g. Mandrake) put libGLU in /usr/X11R6/lib, but 
 697         # wx-config doesn't output that for some reason.  For now, just 
 698         # add it unconditionally but we should really check if the lib is 
 699         # really found there or wx-config should be fixed. 
 700         libdirs
.append("/usr/X11R6/lib") 
 703     # Move the various -I, -D, etc. flags we got from the *config scripts 
 704     # into the distutils lists. 
 705     cflags 
= adjustCFLAGS(cflags
, defines
, includes
) 
 706     lflags 
= adjustLFLAGS(lflags
, libdirs
, libs
) 
 709 #---------------------------------------------------------------------- 
 711     raise 'Sorry, platform not supported...' 
 714 #---------------------------------------------------------------------- 
 715 # post platform setup checks and tweaks, create the full version string 
 716 #---------------------------------------------------------------------- 
 719     BUILD_BASE 
= BUILD_BASE 
+ '.unicode' 
 722 if os
.path
.exists('DAILY_BUILD'): 
 724     VER_FLAGS 
+= '.' + open('DAILY_BUILD').read().strip() 
 726 VERSION 
= "%s.%s.%s.%s%s" % (VER_MAJOR
, VER_MINOR
, VER_RELEASE
, 
 727                              VER_SUBREL
, VER_FLAGS
) 
 730 #---------------------------------------------------------------------- 
 732 #---------------------------------------------------------------------- 
 745              '-I' + opj(WXPY_SRC
, 'src'), 
 750     swig_args
.append('-DwxUSE_UNICODE') 
 753     swig_args
.append('-D_DO_FULL_DOCS') 
 756 swig_deps 
= [ opj(WXPY_SRC
, 'src/my_typemaps.i'), 
 757               opj(WXPY_SRC
, 'src/common.swg'), 
 758               opj(WXPY_SRC
, 'src/pyrun.swg'), 
 761 depends 
= [ #'include/wx/wxPython/wxPython.h', 
 762             #'include/wx/wxPython/wxPython_int.h', 
 766 #---------------------------------------------------------------------- 
 768 #################################### 
 770 #################################### 
 779     FOUND_LIBXML2 
= False 
 781 #--------------------------------------------------------------------------- 
 784 renamerTemplateStart 
= """\ 
 785 // A bunch of %rename directives generated by BuildRenamers in config.py 
 786 // in order to remove the wx prefix from all global scope names. 
 788 #ifndef BUILDING_RENAMERS 
 792 renamerTemplateEnd 
= """ 
 796 wxPythonTemplateStart 
= """\ 
 797 ## This file reverse renames symbols in the wx package to give 
 798 ## them their wx prefix again, for backwards compatibility. 
 800 ## Generated by BuildRenamers in config.py 
 802 # This silly stuff here is so the wxPython.wx module doesn't conflict 
 803 # with the wx package.  We need to import modules from the wx package 
 804 # here, then we'll put the wxPython.wx entry back in sys.modules. 
 807 if sys.modules.has_key('wxPython.wx'): 
 808     _wx = sys.modules['wxPython.wx'] 
 809     del sys.modules['wxPython.wx'] 
 813 sys.modules['wxPython.wx'] = _wx 
 817 # Now assign all the reverse-renamed names: 
 820 wxPythonTemplateEnd 
= """ 
 826 #--------------------------------------------------------------------------- 
 828     def run(self
, destdir
, modname
, xmlfile
, wxPythonDir
="wxPython"):     
 830         assert FOUND_LIBXML2
, "The libxml2 module is required to use the BuildRenamers functionality." 
 832         if not os
.path
.exists(wxPythonDir
): 
 833             os
.mkdir(wxPythonDir
) 
 835         swigDest 
= os
.path
.join(destdir
, "_"+modname
+"_rename.i") 
 836         pyDest 
= os
.path
.join(wxPythonDir
, modname 
+ '.py') 
 838         swigDestTemp 
= tempfile
.mktemp('.tmp') 
 839         swigFile 
= open(swigDestTemp
, "w") 
 840         swigFile
.write(renamerTemplateStart
) 
 842         pyDestTemp 
= tempfile
.mktemp('.tmp') 
 843         pyFile 
= open(pyDestTemp
, "w") 
 844         pyFile
.write(wxPythonTemplateStart 
% modname
) 
 846         print "Parsing XML and building renamers..." 
 847         self
.processXML(xmlfile
, modname
, swigFile
, pyFile
) 
 849         self
.checkOtherNames(pyFile
, modname
, 
 850                         os
.path
.join(destdir
, '_'+modname
+'_reverse.txt')) 
 851         pyFile
.write(wxPythonTemplateEnd
)         
 854         swigFile
.write(renamerTemplateEnd
) 
 857         # Compare the files just created with the existing one and 
 858         # blow away the old one if they are different. 
 859         for dest
, temp 
in [(swigDest
, swigDestTemp
), 
 860                            (pyDest
, pyDestTemp
)]: 
 861             if not os
.path
.exists(dest
): 
 862                 os
.rename(temp
, dest
) 
 863             elif open(dest
).read() != open(temp
).read(): 
 865                 os
.rename(temp
, dest
) 
 867                 print dest 
+ " not changed." 
 870     #--------------------------------------------------------------------------- 
 873     def GetAttr(self
, node
, name
): 
 874         path 
= "./attributelist/attribute[@name='%s']/@value" % name
 
 875         n 
= node
.xpathEval2(path
) 
 882     def processXML(self
, xmlfile
, modname
, swigFile
, pyFile
): 
 884         topnode 
= libxml2
.parseFile(xmlfile
).children
 
 886         # remove any import nodes as we don't need to do renamers for symbols found therein 
 887         imports 
= topnode
.xpathEval2("*/import") 
 892         # do a depth first iteration over what's left 
 900             if node
.name 
== "class": 
 901                 lastClassName 
= name 
= self
.GetAttr(node
, "name") 
 902                 lastClassSymName 
= sym_name 
= self
.GetAttr(node
, "sym_name") 
 909             # renamed constructors 
 910             elif node
.name 
== "constructor": 
 911                 name     
= self
.GetAttr(node
, "name") 
 912                 sym_name 
= self
.GetAttr(node
, "sym_name") 
 918             # only enumitems at the top level 
 919             elif node
.name 
== "enumitem" and node
.parent
.parent
.name 
== "include": 
 920                 name     
= self
.GetAttr(node
, "name") 
 921                 sym_name 
= self
.GetAttr(node
, "sym_name") 
 925             elif node
.name 
in ["cdecl", "constant"]: 
 926                 name      
= self
.GetAttr(node
, "name") 
 927                 sym_name  
= self
.GetAttr(node
, "sym_name") 
 928                 toplevel  
= node
.parent
.name 
== "include" 
 930                 # top-level functions 
 931                 if toplevel 
and self
.GetAttr(node
, "view") == "globalfunctionHandler": 
 934                 # top-level global vars 
 935                 elif toplevel 
and self
.GetAttr(node
, "feature_immutable") == "1": 
 939                 elif self
.GetAttr(node
, "view") == "staticmemberfunctionHandler": 
 940                     name     
= lastClassName 
+ '_' + name
 
 941                     sym_name 
= lastClassSymName 
+ '_' + sym_name
 
 942                     # only output the reverse renamer in this case 
 943                     doRename 
= revOnly 
= True 
 945                 if doRename 
and name 
!= sym_name
: 
 950             if doRename 
and name
: 
 952                 if old
.startswith('wx') and not old
.startswith('wxEVT_'): 
 953                     # remove all wx prefixes except wxEVT_ and write a %rename directive for it 
 956                         swigFile
.write("%%rename(%s)  %35s;\n" % (new
, old
)) 
 958                 # Write assignments to import into the old wxPython namespace 
 959                 if addWX 
and not old
.startswith('wx'): 
 961                 pyFile
.write("%s = wx.%s.%s\n" % (old
, modname
, new
)) 
 963                     pyFile
.write("%sPtr = wx.%s.%sPtr\n" % (old
, modname
, new
)) 
 966     #--------------------------------------------------------------------------- 
 968     def checkOtherNames(self
, pyFile
, moduleName
, filename
): 
 969         if os
.path
.exists(filename
): 
 971             for line 
in file(filename
): 
 972                 if line
.endswith('\n'): 
 974                 if line 
and not line
.startswith('#'): 
 975                     if line
.endswith('*'): 
 976                         prefixes
.append(line
[:-1]) 
 977                     elif line
.find('=') != -1: 
 978                         pyFile
.write("%s\n" % line
) 
 981                         if line
.startswith('wx') or line
.startswith('WX') or line
.startswith('EVT'): 
 983                         pyFile
.write("%s = wx.%s.%s\n" % (wxname
, moduleName
, line
)) 
 987                     "\n\nd = globals()\nfor k, v in wx.%s.__dict__.iteritems():" 
 992                         pyFile
.write("\n    if ") 
 995                         pyFile
.write("\n    elif ") 
 996                     pyFile
.write("k.startswith('%s'):\n        d[k] = v" % p
) 
 997                 pyFile
.write("\ndel d, k, v\n\n") 
1000 #---------------------------------------------------------------------------