]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/my_distutils.py
4 from distutils
.msvccompiler
import MSVCCompiler
5 from distutils
.bcppcompiler
import BCPPCompiler
7 from distutils
.errors
import \
8 DistutilsExecError
, DistutilsPlatformError
, \
9 CompileError
, LibError
, LinkError
10 from distutils
.ccompiler
import \
11 CCompiler
, gen_preprocess_options
, gen_lib_options
13 #----------------------------------------------------------------------
15 class MyMSVCCompiler(MSVCCompiler
):
17 ## def __init__ (self,
21 ## MSVCCompiler.__init__(self, verbose, dry_run, force)
23 ## self.compile_options = [ '/nologo',
29 ## self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
35 ##------------------------------------------------------------
36 ## Override the entire compile method just to add flags to the
37 ## RC command. There should be an easier way to do this from
38 ## distutils directly or in a derived class...
39 ##------------------------------------------------------------
50 (output_dir
, macros
, include_dirs
) = \
51 self
._fix
_compile
_args
(output_dir
, macros
, include_dirs
)
52 (objects
, skip_sources
) = self
._prep
_compile
(sources
, output_dir
)
54 if extra_postargs
is None:
57 pp_opts
= gen_preprocess_options (macros
, include_dirs
)
58 compile_opts
= extra_preargs
or []
59 compile_opts
.append ('/c')
61 compile_opts
.extend (self
.compile_options_debug
)
63 compile_opts
.extend (self
.compile_options
)
65 for i
in range (len (sources
)):
66 src
= sources
[i
] ; obj
= objects
[i
]
67 ext
= (os
.path
.splitext (src
))[1]
70 self
.announce ("skipping %s (%s up-to-date)" % (src
, obj
))
72 self
.mkpath (os
.path
.dirname (obj
))
74 if ext
in self
._c
_extensions
:
75 input_opt
= "/Tc" + os
.path
.abspath(src
) ### RPD
76 elif ext
in self
._cpp
_extensions
:
77 input_opt
= "/Tp" + os
.path
.abspath(src
) ### RPD
78 elif ext
in self
._rc
_extensions
:
79 # compile .RC to .RES file
81 output_opt
= "/fo" + obj
83 self
.spawn ([self
.rc
] + pp_opts
+ ### RPD changed this line
84 [output_opt
] + [input_opt
])
85 except DistutilsExecError
, msg
:
86 raise CompileError
, msg
88 elif ext
in self
._mc
_extensions
:
90 # Compile .MC to .RC file to .RES file.
91 # * '-h dir' specifies the directory for the
92 # generated include file
93 # * '-r dir' specifies the target directory of the
94 # generated RC file and the binary message resource
97 # For now (since there are no options to change this),
98 # we use the source-directory for the include file and
99 # the build directory for the RC file and message
100 # resources. This works at least for win32all.
102 h_dir
= os
.path
.dirname (src
)
103 rc_dir
= os
.path
.dirname (obj
)
105 # first compile .MC to .RC and .H file
106 self
.spawn ([self
.mc
] +
107 ['-h', h_dir
, '-r', rc_dir
] + [src
])
108 base
, _
= os
.path
.splitext (os
.path
.basename (src
))
109 rc_file
= os
.path
.join (rc_dir
, base
+ '.rc')
110 # then compile .RC to .RES file
111 self
.spawn ([self
.rc
] +
112 ["/fo" + obj
] + [rc_file
])
114 except DistutilsExecError
, msg
:
115 raise CompileError
, msg
118 # how to handle this file?
120 "Don't know how to compile %s to %s" % \
123 output_opt
= "/Fo" + obj
125 self
.spawn ([self
.cc
] + compile_opts
+ pp_opts
+
126 [input_opt
, output_opt
] +
128 except DistutilsExecError
, msg
:
129 raise CompileError
, msg
137 from distutils
.file_util
import write_file
138 class MyBCPPCompiler(BCPPCompiler
):
140 ##------------------------------------------------------------
141 ## Override the entire compile method just to add flags to the
142 ## RC command. There should be an easier way to do this from
143 ## distutils directly or in a derived class...
144 ##------------------------------------------------------------
153 extra_postargs
=None):
155 (output_dir
, macros
, include_dirs
) = \
156 self
._fix
_compile
_args
(output_dir
, macros
, include_dirs
)
157 (objects
, skip_sources
) = self
._prep
_compile
(sources
, output_dir
)
159 if extra_postargs
is None:
162 pp_opts
= gen_preprocess_options (macros
, include_dirs
)
163 compile_opts
= extra_preargs
or []
164 compile_opts
.append ('-c')
166 compile_opts
.extend (self
.compile_options_debug
)
168 compile_opts
.extend (self
.compile_options
)
170 for i
in range (len (sources
)):
171 src
= sources
[i
] ; obj
= objects
[i
]
172 ext
= (os
.path
.splitext (src
))[1]
174 if skip_sources
[src
]:
175 self
.announce ("skipping %s (%s up-to-date)" % (src
, obj
))
177 src
= os
.path
.normpath(src
)
178 obj
= os
.path
.normpath(obj
)
179 self
.mkpath(os
.path
.dirname(obj
))
182 # This is already a binary file -- skip it.
183 continue # the 'for' loop
185 # This needs to be compiled to a .res file -- do it now.
187 self
.spawn (["brcc32"] + pp_opts
+ ["-fo"] +
188 [obj
] + [src
]) ### RPD changed this lines only
189 except DistutilsExecError
, msg
:
190 raise CompileError
, msg
191 continue # the 'for' loop
193 # The next two are both for the real compiler.
194 if ext
in self
._c
_extensions
:
196 elif ext
in self
._cpp
_extensions
:
199 # Unknown file type -- no extra options. The compiler
200 # will probably fail, but let it just in case this is a
201 # file the compiler recognizes even if we don't.
204 output_opt
= "-o" + obj
206 # Compiler command line syntax is: "bcc32 [options] file(s)".
207 # Note that the source file names must appear at the end of
210 self
.spawn ([self
.cc
] + compile_opts
+ pp_opts
+
211 [input_opt
, output_opt
] +
212 extra_postargs
+ [src
])
213 except DistutilsExecError
, msg
:
214 raise CompileError
, msg
220 ####################################################################
221 # Now we need to replace cw32mt library used by default by distutils
222 # with cw32mti library as in wxWindows DLL make file
223 # Othervise we obtain Windows "Core dump" ;-).
225 # Evgeny A Cherkashin <eugeneai@icc.ru>
227 ####################################################################
236 runtime_library_dirs
=None,
243 # XXX this ignores 'build_temp'! should follow the lead of
246 (objects
, output_dir
) = self
._fix
_object
_args
(objects
, output_dir
)
247 (libraries
, library_dirs
, runtime_library_dirs
) = \
248 self
._fix
_lib
_args
(libraries
, library_dirs
, runtime_library_dirs
)
250 if runtime_library_dirs
:
251 self
.warn ("I don't know what to do with 'runtime_library_dirs': "
252 + str (runtime_library_dirs
))
254 if output_dir
is not None:
255 output_filename
= os
.path
.join (output_dir
, output_filename
)
257 if self
._need
_link
(objects
, output_filename
):
259 # Figure out linker args based on type of target.
260 if target_desc
== CCompiler
.EXECUTABLE
:
261 startup_obj
= 'c0w32'
263 ld_args
= self
.ldflags_exe_debug
[:]
265 ld_args
= self
.ldflags_exe
[:]
267 startup_obj
= 'c0d32'
269 ld_args
= self
.ldflags_shared_debug
[:]
271 ld_args
= self
.ldflags_shared
[:]
274 # Create a temporary exports file for use by the linker
275 if export_symbols
is None:
278 head
, tail
= os
.path
.split (output_filename
)
279 modname
, ext
= os
.path
.splitext (tail
)
280 temp_dir
= os
.path
.dirname(objects
[0]) # preserve tree structure
281 def_file
= os
.path
.join (temp_dir
, '%s.def' % modname
)
282 contents
= ['EXPORTS']
283 for sym
in (export_symbols
or []):
284 contents
.append(' %s=_%s' % (sym
, sym
))
285 self
.execute(write_file
, (def_file
, contents
),
286 "writing %s" % def_file
)
288 # Borland C++ has problems with '/' in paths
289 objects2
= map(os
.path
.normpath
, objects
)
290 # split objects in .obj and .res files
291 # Borland C++ needs them at different positions in the command line
292 objects
= [startup_obj
]
294 for file in objects2
:
295 (base
, ext
) = os
.path
.splitext(os
.path
.normcase(file))
297 resources
.append(file)
302 for l
in library_dirs
:
303 ld_args
.append("/L%s" % os
.path
.normpath(l
))
304 ld_args
.append("/L.") # we sometimes use relative paths
306 # list of object files
307 ld_args
.extend(objects
)
309 # XXX the command-line syntax for Borland C++ is a bit wonky;
310 # certain filenames are jammed together in one big string, but
311 # comma-delimited. This doesn't mesh too well with the
312 # Unix-centric attitude (with a DOS/Windows quoting hack) of
313 # 'spawn()', so constructing the argument list is a bit
314 # awkward. Note that doing the obvious thing and jamming all
315 # the filenames and commas into one argument would be wrong,
316 # because 'spawn()' would quote any filenames with spaces in
317 # them. Arghghh!. Apparently it works fine as coded...
319 # name of dll/exe file
320 ld_args
.extend([',',output_filename
])
321 # no map file and start libraries
324 for lib
in libraries
:
325 # see if we find it and if there is a bcpp specific lib
327 libfile
= self
.find_library_file(library_dirs
, lib
, debug
)
330 # probably a BCPP internal library -- don't warn
331 # self.warn('library %s not found.' % lib)
333 # full name which prefers bcpp_xxx.lib over xxx.lib
334 ld_args
.append(libfile
)
336 # some default libraries
337 ld_args
.append ('import32')
338 ld_args
.append ('cw32mti') ### mt->mti (as in wx2)
340 # def file for export symbols
341 ld_args
.extend([',',def_file
])
344 ld_args
.extend(resources
)
348 ld_args
[:0] = extra_preargs
350 ld_args
.extend(extra_postargs
)
352 self
.mkpath (os
.path
.dirname (output_filename
))
354 self
.spawn ([self
.linker
] + ld_args
)
355 except DistutilsExecError
, msg
:
359 self
.announce ("skipping %s (up-to-date)" % output_filename
)
365 #----------------------------------------------------------------------
366 # Hack this module and class into the distutils...
368 from distutils
import ccompiler
370 if hasattr(ccompiler
, "default_compiler"):
371 ccompiler
.default_compiler
['nt'] = 'my_msvc'
372 elif hasattr(ccompiler
, "_default_compilers"):
373 lst
= list(ccompiler
._default
_compilers
)
374 lst
.remove( ('nt', 'msvc') )
375 lst
.append( ('nt', 'my_msvc') )
376 ccompiler
._default
_compilers
= tuple(lst
)
379 ccompiler
.compiler_class
['my_msvc'] = ('my_distutils',
381 'My MSVC derived class')
384 ccompiler
.compiler_class
['my_bcpp'] = ('my_distutils',
386 'My BCPP derived class')
388 # make it look like it is part of the package...
390 sys
.modules
['distutils.my_distutils'] = my_distutils
393 #----------------------------------------------------------------------
394 # More hacking... Distutils in Python 2.1 changed the strip_dir flag
395 # passed to object_filenames to true, which causes problems for us since
396 # there are a few duplicate source/object names between some of the
397 # extensions in wxPython. This hack replaces the CCompiler._prep_compile
398 # method with this one.
400 from distutils
.dep_util
import newer_pairwise
402 def _prep_compile (self
, sources
, output_dir
):
403 """Determine the list of object files corresponding to 'sources',
404 and figure out which ones really need to be recompiled. Return a
405 list of all object files and a dictionary telling which source
406 files can be skipped.
408 # Get the list of expected output (object) files
409 objects
= self
.object_filenames (sources
,
411 output_dir
=output_dir
)
414 skip_source
= {} # rebuild everything
415 for source
in sources
:
416 skip_source
[source
] = 0
418 # Figure out which source files we have to recompile according
419 # to a simplistic check -- we just compare the source and
420 # object file, no deep dependency checking involving header
422 skip_source
= {} # rebuild everything
423 for source
in sources
: # no wait, rebuild nothing
424 skip_source
[source
] = 1
426 (n_sources
, n_objects
) = newer_pairwise (sources
, objects
)
427 for source
in n_sources
: # no really, only rebuild what's
428 skip_source
[source
] = 0 # out-of-date
430 return (objects
, skip_source
)
434 CCompiler
._prep
_compile
= _prep_compile
439 #----------------------------------------------------------------------
440 # Run SWIG the way I want it done
442 def run_swig(files
, dir, gendir
, package
, USE_SWIG
, force
, swig_args
, swig_deps
=[]):
443 from distutils
.file_util
import copy_file
444 from distutils
.dep_util
import newer
445 from distutils
.spawn
import spawn
450 basefile
= os
.path
.splitext(file)[0]
451 i_file
= os
.path
.join(dir, file)
452 py_file
= os
.path
.join(dir, gendir
, basefile
+'.py')
453 cpp_file
= os
.path
.join(dir, gendir
, basefile
+'.cpp')
455 sources
.append(cpp_file
)
458 for dep
in swig_deps
:
459 if newer(dep
, py_file
) or newer(dep
, cpp_file
):
463 if force
or newer(i_file
, py_file
) or newer(i_file
, cpp_file
):
464 # we need forward slashes here even on win32
465 cpp_file
= string
.join(string
.split(cpp_file
, '\\'), '/')
466 i_file
= string
.join(string
.split(i_file
, '\\'), '/')
468 cmd
= ['swig'] + swig_args
+ ['-I'+dir, '-c', '-o', cpp_file
, i_file
]
469 spawn(cmd
, verbose
=1)
471 # copy the generated python file to the package directory
472 copy_file(py_file
, package
, update
=not force
, verbose
=0)
479 #----------------------------------------------------------------------
480 # Update local copies of wxWindows contrib files
483 def contrib_copy_tree(src
, dest
, verbose
=0):
484 from distutils
.dir_util
import mkpath
, copy_tree
486 mkpath(dest
, verbose
=verbose
)
487 copy_tree(src
, dest
, update
=1, verbose
=verbose
)