]>
git.saurik.com Git - wxWidgets.git/blob - utils/wxPython/distrib/build.py
2 #----------------------------------------------------------------------------
4 # Purpose: This script is used to build wxPython. It reads a build
5 # configuration file in the requested project directory and
6 # based on the contents of the file can build Makefiles for
7 # unix or win32, and can execute make with various options
8 # potentially automating the entire build/install/clean process
9 # from a single command.
13 # Created: 18-Aug-1999
15 # Copyright: (c) 1999 by Total Control Software
16 # Licence: wxWindows license
17 #----------------------------------------------------------------------------
21 This script is used to build wxPython. It reads a build configuration
22 file in the requested project directory and based on the contents of
23 the file can build Makefiles for unix or win32, and can execute make
24 with various options potentially automating the entire
25 build/install/clean process from a single command.
27 The default action is to build the Makefile and exit.
30 -C dir CD to dir before doing anything
31 -B file Use file as the build configuration (default ./build.cfg)
32 -M file Use file as the name of the makefile to create
35 -b Build the module (runs make)
36 -i Install the module (runs make install)
37 -c Cleanup (runs make clean)
38 -u Uninstall (runs make uninstall)
45 The build configuration file lists targets, source files and options
46 for the the build process. The contents of the build.cfg are used to
47 dynamically generate the Makefile.
49 To prevent you from getting screwed when the default build.cfg is
50 updated, you can override the values in build.cfg by putting your
51 custom definitions in a file named build.local. You can also place a
52 build.local file in the parent directory, or even in the grandparent
53 directory for project-wide overrides. Finally, command-line arguments
54 of the form NAME=VALUE can also be used to override simple configuration
55 values. The order of evaluation is:
57 0. comman-line flags (-M, -b, etc.)
59 2. ../../build.local (if present)
60 3. ../build.local (if present)
61 4. ./build.local (if present)
62 5. command-line NAME=VALUEs
64 The config files are actually just Python files that get exec'ed in a
65 separate namespace which is then used later as a configuration object.
66 This keeps the build script simple in that it doesn't have to parse
67 anything, and the config files can be much more than just names and
68 values as any pretty much any python code can be executed. The global
69 variables set in the config namespace are what are used later as
75 The following variables can be set in the config files. Only a few are
76 required, the rest will either have suitable defaults or will be
77 calculated from your current Python runtime environment.
79 MODULE The name of the extension module to produce
80 SWIGFILES A list of files that should be run through SWIG
81 SWIGFLAGS Flags for SWIG
82 SOURCES Other C/C++ sources that should be part of the module
83 PYFILES Other Python files that should be installed with the module
84 CFLAGS Flags to be used by the compiler
85 LFLAGS Flags to be used at the link step
86 LIBS Libraries to be linked with
88 OTHERCFLAGS Extra flags to append to CFLAGS
89 OTHERLFLAGS Extra flags to append to LFLAGS
90 OTHERSWIGFLAGS Extra flags to append to SWIGFLAGS
91 OTHERLIBS Other libraries to be linked with, in addition to LIBS
92 OTHERTARGETS Other targets to be placed on the default rule line
94 Other targets to be placed on the install rule line
95 OTHERRULES This text is placed at the end of the makefile and
96 will typically be used for adding rules and such
97 DEFAULTRULE Text to be used for the default rule in the makefile
99 TARGETDIR Destination for the install step
101 MAKE The make program to use
102 MAKEFILE The name of the makefile
104 runBuild Setting this to 1 is eqivalent to the -b flag
105 runInstall Setting this to 1 is eqivalent to the -i flag
106 runClean Setting this to 1 is eqivalent to the -c flag
107 runUninstall Setting this to 1 is eqivalent to the -u flag
109 PYVERSION Version number of Python used in pathnames
110 PYPREFIX The root of the Python install
111 EXECPREFIX The root of the Python install for binary files
112 PYTHONLIB The Python link library
116 import sys
, os
, string
, getopt
118 #----------------------------------------------------------------------------
119 # This is really the wxPython version number, and will be placed in the
120 # Makefiles for use with the distribution related targets.
122 __version__
= '2.1b3'
124 #----------------------------------------------------------------------------
128 opts
, args
= getopt
.getopt(args
[1:], 'C:B:M:bicu')
133 if not os
.environ
.has_key('WXWIN'):
134 print "WARNING: WXWIN is not set in the environment. WXDIR may not\n"\
135 " be set properly in the makefile, you will have to \n"\
136 " set the environment variable or override in build.local."
139 bldCfgLocal
= 'build.local'
140 MAKEFILE
= 'Makefile'
146 for flag
, value
in opts
:
147 if flag
== '-C': os
.chdir(value
)
148 elif flag
== '-B': bldCfgFile
= value
149 elif flag
== '-M': makefile
= value
150 elif flag
== '-b': runBuild
= 1
151 elif flag
== '-c': runClean
= 1
152 elif flag
== '-i': runInstall
= 1
153 elif flag
== '-u': runUninstall
= 1
155 elif flag
== '-h': usage(); sys
.exit(1)
156 else: usage(); sys
.exit(1)
158 config
= BuildConfig(bldCfg
= bldCfg
,
159 bldCfgLocal
= bldCfgLocal
,
162 runInstall
= runInstall
,
164 runUninstall
= runUninstall
)
166 if config
.readConfigFiles(args
):
167 config
.makeMakefile()
171 cmd
= "%s -f %s" % (config
.MAKE
, config
.MAKEFILE
)
172 print "Running:", cmd
175 if not err
and config
.runInstall
:
176 cmd
= "%s -f %s install" % (config
.MAKE
, config
.MAKEFILE
)
177 print "Running:", cmd
181 if not err
and config
.runClean
:
182 cmd
= "%s -f %s clean" % (config
.MAKE
, config
.MAKEFILE
)
183 print "Running:", cmd
186 if not err
and config
.runUninstall
:
187 cmd
= "%s -f %s uninstall" % (config
.MAKE
, config
.MAKEFILE
)
188 print "Running:", cmd
193 #----------------------------------------------------------------------------
198 #----------------------------------------------------------------------------
201 if sys
.platform
!= 'win32':
202 st
= string
.join(string
.split(st
, '\\'), '/')
205 #----------------------------------------------------------------------------
208 return string
.join(string
.split(string
.strip(st
), ' '), ' \\\n\t')
210 #----------------------------------------------------------------------------
213 # remove any leading paths, retrieve only file name. Used while
214 # parsing the SOURCES file list, so that object files are local,
215 # while source may be anywere)
216 if sys
.platform
== 'win32':
220 return string
.split(st
,sep
)[-1]
222 #----------------------------------------------------------------------------
225 def __init__(self
, **kw
):
226 self
.__dict
__.update(kw
)
229 #------------------------------------------------------------
230 def setDefaults(self
):
231 self
.VERSION
= __version__
234 self
.SWIGFLAGS
= '-c++ -shadow -python -dnone -I$(WXPSRCDIR)'
238 self
.OTHERCFLAGS
= ''
239 self
.OTHERLFLAGS
= ''
240 self
.OTHERSWIGFLAGS
= ''
242 self
.OTHERTARGETS
= ''
243 self
.OTHERINSTALLTARGETS
= ''
245 self
.DEFAULTRULE
= 'default: $(GENCODEDIR) $(TARGET)'
246 self
.PYVERSION
= sys
.version
[:3]
247 self
.PYPREFIX
= sys
.prefix
248 self
.EXECPREFIX
= sys
.exec_prefix
249 self
.WXDIR
= '$(WXWIN)'
251 self
.WXP_USE_THREAD
= '1'
252 self
.WXUSINGDLL
= '1'
254 self
.WXPSRCDIR
= '$(WXDIR)/utils/wxPython/src'
257 if sys
.platform
== 'win32':
259 self
.PYTHONLIB
= '$(PYPREFIX)\\libs\\python15.lib'
260 self
.TARGETDIR
= '$(PYPREFIX)\\wxPython'
261 self
.LIBS
= '$(PYTHONLIB) $(WXPSRCDIR)\wxc.lib'
262 self
.GENCODEDIR
= 'msw'
263 self
.SWIGTOOLKITFLAG
= '-D__WXMSW__'
265 self
.TARGET
= '$(MODULE).pyd'
266 self
.CFLAGS
= '-I$(PYPREFIX)\include -I$(WXPSRCDIR) -I. /Fp$(MODULE).pch /YXhelpers.h -DSWIG_GLOBAL -DHAVE_CONFIG_H $(THREAD) '
267 self
.LFLAGS
= '$(DEBUGLFLAGS) /DLL /subsystem:windows,3.50 /machine:I386 /nologo'
270 self
.OVERRIDEFLAGS
= '/GX-'
274 self
.PYLIB
= '$(EXECPREFIX)/lib/python$(PYVERSION)'
275 self
.LIBPL
= '$(PYLIB)/config'
276 self
.PYTHONLIB
= '$(LIBPL)/libpython$(PYVERSION).a'
277 self
.TARGETDIR
= '$(EXECPREFIX)/lib/python$(PYVERSION)/site-packages/wxPython'
278 self
.TARGET
= '$(MODULE)module$(SO)'
280 self
.HELPERLIB
= 'wxPyHelpers'
281 self
.HELPERLIBDIR
= '/usr/local/lib'
282 self
.CFLAGS
= '-DSWIG_GLOBAL -DHAVE_CONFIG_H $(THREAD) -I. '\
283 '`wx-config --cflags` -I$(PYINCLUDE) -I$(EXECINCLUDE) '\
285 self
.LFLAGS
= '-L$(WXPSRCDIR) `wx-config --libs`'
286 self
.LIBS
= '-l$(HELPERLIB)'
288 # **** what to do when I start supporting Motif, etc.???
289 self
.GENCODEDIR
= 'gtk'
290 self
.SWIGTOOLKITFLAG
= '-D__WXGTK__'
292 # Extract a few things from Python's Makefile...
294 filename
= os
.path
.join(self
.EXECPREFIX
,
295 'lib/python'+self
.PYVERSION
,
297 mfText
= string
.split(open(filename
, 'r').read(), '\n')
299 raise SystemExit, "Python development files not found"
301 self
.CCC
= self
.findMFValue(mfText
, 'CCC')
303 print "Warning: C++ compiler not specified (CCC). Assuming c++"
305 self
.CC
= self
.findMFValue(mfText
, 'CC')
307 print "Warning: C compiler not specified (CCC). Assuming cc"
309 self
.OPT
= self
.findMFValue(mfText
, 'OPT')
310 self
.SO
= self
.findMFValue(mfText
, 'SO')
311 self
.LDSHARED
= self
.findMFValue(mfText
, 'LDSHARED')
312 self
.CCSHARED
= self
.findMFValue(mfText
, 'CCSHARED')
313 #self.LINKFORSHARED = self.findMFValue(mfText, 'LINKFORSHARED')
314 #self. = self.findMFValue(mfText, '')
315 #self. = self.findMFValue(mfText, '')
318 # The majority of cases will require LDSHARED to be
319 # modified to use the C++ driver instead of the C driver
320 # for linking. We'll try to do it here and if we goof up
321 # then the user can correct it in their build.local file.
322 self
.LDSHARED
= string
.join(['$(CCC)'] +
323 string
.split(self
.LDSHARED
, ' ')[1:],
327 #------------------------------------------------------------
328 def findMFValue(self
, mfText
, st
):
329 # Find line begining with st= and return the value
330 # Regex would probably be to cooler way to do this, but
331 # I think this is the most understandable.
333 if string
.find(line
, st
+'=') == 0:
334 st
= string
.strip(line
[len(st
)+1:])
338 #------------------------------------------------------------
339 def makeMakefile(self
):
341 # make a list of object file names
343 for name
in self
.SWIGFILES
:
344 objects
= objects
+ os
.path
.splitext(name
)[0] + self
.OBJEXT
+ ' '
345 for name
in self
.SOURCES
:
346 obj
= strippath(name
)
347 objects
= objects
+ os
.path
.splitext(obj
)[0] + self
.OBJEXT
+ ' '
348 self
.OBJECTS
= splitlines(objects
)
351 # now build the text for the dependencies
353 for name
in self
.SWIGFILES
:
354 text
= '$(GENCODEDIR)/%s.cpp $(GENCODEDIR)/%s.py : %s.i\n' \
355 '$(TARGETDIR)\\%s.py : $(GENCODEDIR)\\%s.py\n' % \
356 tuple([os
.path
.splitext(name
)[0]] * 5)
357 depends
= depends
+ text
358 for name
in self
.PYFILES
:
359 text
= '$(TARGETDIR)\\%s.py : %s.py\n' % \
360 tuple([os
.path
.splitext(name
)[0]] * 2)
361 depends
= depends
+ text
362 self
.DEPENDS
= swapslash(depends
)
365 # and the list of .py files
367 for name
in self
.SWIGFILES
:
368 pymodules
= pymodules
+ '$(TARGETDIR)\\%s.py ' % os
.path
.splitext(name
)[0]
369 for name
in self
.PYFILES
:
370 pymodules
= pymodules
+ '$(TARGETDIR)\\%s.py ' % os
.path
.splitext(name
)[0]
371 self
.PYMODULES
= splitlines(swapslash(pymodules
))
375 # finally, build the makefile
376 if sys
.platform
== 'win32':
378 self
.RESFILE
= '$(MODULE).res'
379 self
.RESRULE
= '$(MODULE).res : $(MODULE).rc $(WXDIR)\\include\\wx\\msw\\wx.rc\n\t'\
380 '$(rc) -r /i$(WXDIR)\\include -fo$@ $(MODULE).rc'
381 text
= win32Template
% self
.__dict
__
383 text
= unixTemplate
% self
.__dict
__
384 f
= open(self
.MAKEFILE
, 'w')
388 print "Makefile created: ", self
.MAKEFILE
391 #------------------------------------------------------------
392 def readConfigFiles(self
, args
):
393 return self
.processFile(self
.bldCfg
, 1) and \
394 self
.processFile(os
.path
.join('../..', self
.bldCfgLocal
)) and \
395 self
.processFile(os
.path
.join('..', self
.bldCfgLocal
)) and \
396 self
.processFile(os
.path
.join('.', self
.bldCfgLocal
)) and \
397 self
.processArgs(args
)
399 #------------------------------------------------------------
400 def processFile(self
, filename
, required
=0):
402 text
= open(filename
, 'r').read()
405 print "Unable to open %s" % filename
411 exec(text
, self
.__dict
__)
413 print "Error evaluating %s" % filename
415 traceback
.print_exc()
420 #------------------------------------------------------------
421 def processArgs(self
, args
):
424 pair
= string
.split(st
, '=')
427 self
.__dict
__[name
] = value
429 print "Error parsing command-line: %s" % st
435 #------------------------------------------------------------
441 #----------------------------------------------------------------------------
442 #----------------------------------------------------------------------------
445 #----------------------------------------------------------------------
446 # This makefile was autogenerated from build.py. Your changes will be
447 # lost if the generator is run again. You have been warned.
448 #----------------------------------------------------------------------
451 VERSION = %(VERSION)s
453 SWIGFLAGS = %(SWIGFLAGS)s %(SWIGTOOLKITFLAG)s %(OTHERSWIGFLAGS)s
454 CFLAGS = %(CFLAGS)s %(OTHERCFLAGS)s
455 LFLAGS = %(LFLAGS)s %(OTHERLFLAGS)s
456 PYVERSION = %(PYVERSION)s
457 PYPREFIX = %(PYPREFIX)s
458 EXECPREFIX = %(EXECPREFIX)s
459 PYTHONLIB = %(PYTHONLIB)s
461 WXP_USE_THREAD = %(WXP_USE_THREAD)s
462 WXUSINGDLL = %(WXUSINGDLL)s
463 GENCODEDIR = %(GENCODEDIR)s
464 RESFILE = %(RESFILE)s
465 WXPSRCDIR = %(WXPSRCDIR)s
468 TARGETDIR = %(TARGETDIR)s
470 OBJECTS = %(OBJECTS)s
471 PYMODULES = %(PYMODULES)s
477 !if "$(FINAL)" == "0"
478 DEBUGLFLAGS = /DEBUG /INCREMENTAL:YES
480 DEBUGLFLAGS = /INCREMENTAL:NO
482 !if "$(WXP_USE_THREAD)" == "1"
483 THREAD=-DWXP_USE_THREAD=1
490 OVERRIDEFLAGS=%(OVERRIDEFLAGS)s %(OTHERCFLAGS)s
491 EXTRAFLAGS = %(CFLAGS)s
493 LFLAGS = %(LFLAGS)s %(OTHERLFLAGS)s
494 EXTRALIBS = %(LIBS)s %(OTHERLIBS)s
496 #----------------------------------------------------------------------
498 !include $(WXDIR)\\src\\makevc.env
500 #----------------------------------------------------------------------
502 %(DEFAULTRULE)s %(OTHERTARGETS)s
506 install: $(TARGETDIR) $(TARGETDIR)\\$(TARGET) pycfiles %(OTHERINSTALLTARGETS)s
523 -erase $(TARGETDIR)\\$(TARGET)
526 #----------------------------------------------------------------------
527 # implicit rule for compiling .cpp and .c files
530 $(CPPFLAGS) /c /Tp $<
533 {$(GENCODEDIR)}.cpp{}.obj:
535 $(CPPFLAGS) /c /Tp $<
545 # Implicit rules to run SWIG
546 {}.i{$(GENCODEDIR)}.cpp:
547 swig $(SWIGFLAGS) -c -o $@ $<
549 {}.i{$(GENCODEDIR)}.py:
550 swig $(SWIGFLAGS) -c -o $(GENCODEDIR)\\tmp_wrap.cpp $<
551 -erase $(GENCODEDIR)\\tmp_wrap.cpp
554 {$(GENCODEDIR)}.py{$(TARGETDIR)}.py:
557 {}.py{$(TARGETDIR)}.py:
560 #----------------------------------------------------------------------
562 $(TARGET) : $(DUMMYOBJ) $(WXLIB) $(OBJECTS) $(RESFILE)
565 $(LFLAGS) /def:$(MODULE).def /implib:./$(MODULE).lib
566 $(DUMMYOBJ) $(OBJECTS) $(RESFILE)
574 $(TARGETDIR)\\$(TARGET) : $(TARGET)
578 pycfiles : $(PYMODULES)
579 $(EXECPREFIX)\\python $(PYPREFIX)\\Lib\\compileall.py -l $(TARGETDIR)
580 $(EXECPREFIX)\\python -O $(PYPREFIX)\Lib\\compileall.py -l $(TARGETDIR)
589 #----------------------------------------------------------------------
593 #----------------------------------------------------------------------
599 #----------------------------------------------------------------------------
600 #----------------------------------------------------------------------------
601 #----------------------------------------------------------------------------
604 #----------------------------------------------------------------------
605 # This makefile was autogenerated from build.py. Your changes will be
606 # lost if the generator is run again. You have been warned.
607 #----------------------------------------------------------------------
612 VERSION = %(VERSION)s
614 SWIGFLAGS = %(SWIGFLAGS)s %(SWIGTOOLKITFLAG)s %(OTHERSWIGFLAGS)s
615 CFLAGS = %(CFLAGS)s %(OTHERCFLAGS)s
616 LFLAGS = %(LFLAGS)s %(OTHERLFLAGS)s
617 LIBS = %(LIBS)s %(OTHERLIBS)s
618 PYVERSION = %(PYVERSION)s
619 PYPREFIX = %(PYPREFIX)s
620 EXECPREFIX = %(EXECPREFIX)s
621 PYINCLUDE = $(PYPREFIX)/include/python$(PYVERSION)
622 EXECINCLUDE = $(EXECPREFIX)/include/python$(PYVERSION)
625 PYTHONLIB = %(PYTHONLIB)s
627 WXP_USE_THREAD = %(WXP_USE_THREAD)s
628 GENCODEDIR = %(GENCODEDIR)s
629 WXPSRCDIR = %(WXPSRCDIR)s
630 HELPERLIB = %(HELPERLIB)s
631 HELPERLIBDIR = %(HELPERLIBDIR)s
633 TARGETDIR = %(TARGETDIR)s
640 LDSHARED = %(LDSHARED)s
641 CCSHARED = %(CCSHARED)s
644 OBJECTS = %(OBJECTS)s
645 PYMODULES = %(PYMODULES)s
649 ifeq ($(WXP_USE_THREAD), 1)
650 THREAD=-DWXP_USE_THREAD
653 #----------------------------------------------------------------------
655 %(DEFAULTRULE)s %(OTHERTARGETS)s
657 install: $(TARGETDIR) $(TARGETDIR)/$(TARGET) pycfiles %(OTHERINSTALLTARGETS)s
664 -rm -f $(TARGETDIR)/$(TARGET)
668 #----------------------------------------------------------------------
671 $(CCC) $(CCSHARED) $(CFLAGS) $(OTHERCFLAGS) -c $<
673 %%.o : $(GENCODEDIR)/%%.cpp
674 $(CCC) $(CCSHARED) $(CFLAGS) $(OTHERCFLAGS) -c $<
677 $(CC) $(CCSHARED) $(CFLAGS) $(OTHERCFLAGS) -c $<
679 %%.o : $(GENCODEDIR)/%%.c
680 $(CC) $(CCSHARED) $(CFLAGS) $(OTHERCFLAGS) -c $<
682 $(GENCODEDIR)/%%.cpp : %%.i
683 swig $(SWIGFLAGS) -c -o $@ $<
685 $(GENCODEDIR)/%%.py : %%.i
686 swig $(SWIGFLAGS) -c -o $(GENCODEDIR)/tmp_wrap.cpp $<
687 rm $(GENCODEDIR)/tmp_wrap.cpp
692 $(TARGETDIR)/%% : $(GENCODEDIR)/%%
695 #----------------------------------------------------------------------
699 #----------------------------------------------------------------------
701 $(TARGET) : $(OBJECTS)
702 $(LDSHARED) $(OBJECTS) $(LFLAGS) $(LIBS) $(OTHERLIBS) -o $(TARGET)
706 pycfiles : $(PYMODULES)
707 $(EXECPREFIX)/bin/python $(PYLIB)/compileall.py -l $(TARGETDIR)
708 $(EXECPREFIX)/bin/python -O $(PYLIB)/compileall.py -l $(TARGETDIR)
717 #----------------------------------------------------------------------
727 #----------------------------------------------------------------------------
729 if __name__
== '__main__':
732 #----------------------------------------------------------------------------