]> git.saurik.com Git - wxWidgets.git/blob - wxPython/my_distutils.py
Some mods
[wxWidgets.git] / wxPython / my_distutils.py
1
2 import sys, os, string
3
4 from distutils.msvccompiler import MSVCCompiler
5
6 from distutils.errors import \
7 DistutilsExecError, DistutilsPlatformError, \
8 CompileError, LibError, LinkError
9 from distutils.ccompiler import \
10 CCompiler, gen_preprocess_options, gen_lib_options
11
12 #----------------------------------------------------------------------
13
14 class MyMSVCCompiler(MSVCCompiler):
15
16 ##------------------------------------------------------------
17 ## Override the entire compile method just to add flags to the
18 ## RC command. There should be an easier way to do this from
19 ## distutils directly or in a derived class...
20 ##------------------------------------------------------------
21
22 def compile (self,
23 sources,
24 output_dir=None,
25 macros=None,
26 include_dirs=None,
27 debug=0,
28 extra_preargs=None,
29 extra_postargs=None):
30
31 (output_dir, macros, include_dirs) = \
32 self._fix_compile_args (output_dir, macros, include_dirs)
33 (objects, skip_sources) = self._prep_compile (sources, output_dir)
34
35 if extra_postargs is None:
36 extra_postargs = []
37
38 pp_opts = gen_preprocess_options (macros, include_dirs)
39 compile_opts = extra_preargs or []
40 compile_opts.append ('/c')
41 if debug:
42 compile_opts.extend (self.compile_options_debug)
43 else:
44 compile_opts.extend (self.compile_options)
45
46 for i in range (len (sources)):
47 src = sources[i] ; obj = objects[i]
48 ext = (os.path.splitext (src))[1]
49
50 if skip_sources[src]:
51 self.announce ("skipping %s (%s up-to-date)" % (src, obj))
52 else:
53 self.mkpath (os.path.dirname (obj))
54
55 if ext in self._c_extensions:
56 input_opt = "/Tc" + os.path.abspath(src)
57 elif ext in self._cpp_extensions:
58 input_opt = "/Tp" + os.path.abspath(src)
59 elif ext in self._rc_extensions:
60 # compile .RC to .RES file
61 input_opt = src
62 output_opt = "/fo" + obj
63 try:
64 self.spawn ([self.rc] + pp_opts + ### RPD changed this line only
65 [output_opt] + [input_opt])
66 except DistutilsExecError, msg:
67 raise CompileError, msg
68 continue
69 elif ext in self._mc_extensions:
70
71 # Compile .MC to .RC file to .RES file.
72 # * '-h dir' specifies the directory for the
73 # generated include file
74 # * '-r dir' specifies the target directory of the
75 # generated RC file and the binary message resource
76 # it includes
77 #
78 # For now (since there are no options to change this),
79 # we use the source-directory for the include file and
80 # the build directory for the RC file and message
81 # resources. This works at least for win32all.
82
83 h_dir = os.path.dirname (src)
84 rc_dir = os.path.dirname (obj)
85 try:
86 # first compile .MC to .RC and .H file
87 self.spawn ([self.mc] +
88 ['-h', h_dir, '-r', rc_dir] + [src])
89 base, _ = os.path.splitext (os.path.basename (src))
90 rc_file = os.path.join (rc_dir, base + '.rc')
91 # then compile .RC to .RES file
92 self.spawn ([self.rc] +
93 ["/fo" + obj] + [rc_file])
94
95 except DistutilsExecError, msg:
96 raise CompileError, msg
97 continue
98 else:
99 # how to handle this file?
100 raise CompileError (
101 "Don't know how to compile %s to %s" % \
102 (src, obj))
103
104 output_opt = "/Fo" + obj
105 try:
106 self.spawn ([self.cc] + compile_opts + pp_opts +
107 [input_opt, output_opt] +
108 extra_postargs)
109 except DistutilsExecError, msg:
110 raise CompileError, msg
111
112 return objects
113
114 # compile ()
115
116
117
118 ##------------------------------------------------------------
119 ## Now override the link() method to change where the import
120 ## library is placed. Hopefully distutils will be updated
121 ## someday to make this configurable...
122 ##------------------------------------------------------------
123
124 def link (self,
125 target_desc,
126 objects,
127 output_filename,
128 output_dir=None,
129 libraries=None,
130 library_dirs=None,
131 runtime_library_dirs=None,
132 export_symbols=None,
133 debug=0,
134 extra_preargs=None,
135 extra_postargs=None,
136 build_temp=None):
137
138 (objects, output_dir) = self._fix_object_args (objects, output_dir)
139 (libraries, library_dirs, runtime_library_dirs) = \
140 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
141
142 if runtime_library_dirs:
143 self.warn ("I don't know what to do with 'runtime_library_dirs': "
144 + str (runtime_library_dirs))
145
146 lib_opts = gen_lib_options (self,
147 library_dirs, runtime_library_dirs,
148 libraries)
149 if output_dir is not None:
150 output_filename = os.path.join (output_dir, output_filename)
151
152 if self._need_link (objects, output_filename):
153
154 if target_desc == CCompiler.EXECUTABLE:
155 if debug:
156 ldflags = self.ldflags_shared_debug[1:]
157 else:
158 ldflags = self.ldflags_shared[1:]
159 else:
160 if debug:
161 ldflags = self.ldflags_shared_debug
162 else:
163 ldflags = self.ldflags_shared
164
165 export_opts = []
166 for sym in (export_symbols or []):
167 export_opts.append("/EXPORT:" + sym)
168
169 ld_args = (ldflags + lib_opts + export_opts +
170 objects + ['/OUT:' + output_filename])
171
172 # The MSVC linker generates .lib and .exp files, which cannot be
173 # suppressed by any linker switches. The .lib files may even be
174 # needed! Make sure they are generated in the temporary build
175 # directory. Since they have different names for debug and release
176 # builds, they can go into the same directory.
177 if export_symbols is not None:
178 (dll_name, dll_ext) = os.path.splitext(
179 os.path.basename(output_filename))
180
181 ## The old code
182 ##implib_file = os.path.join(
183 ## os.path.dirname(objects[0]),
184 ## self.library_filename(dll_name))
185
186 ## The new
187 implib_file = os.path.join('build', 'ilib',
188 self.library_filename(dll_name))
189 self.mkpath(os.path.dirname(implib_file))
190
191 ld_args.append ('/IMPLIB:' + implib_file)
192
193 if extra_preargs:
194 ld_args[:0] = extra_preargs
195 if extra_postargs:
196 ld_args.extend(extra_postargs)
197
198 self.mkpath (os.path.dirname (output_filename))
199 try:
200 self.spawn ([self.linker] + ld_args)
201 except DistutilsExecError, msg:
202 raise LinkError, msg
203
204 else:
205 self.announce ("skipping %s (up-to-date)" % output_filename)
206
207 # link ()
208
209
210
211 #----------------------------------------------------------------------
212 # Hack this module and class into the distutils...
213
214 from distutils import ccompiler
215
216 ccompiler.default_compiler['nt'] = 'my_msvc'
217 ccompiler.compiler_class['my_msvc'] = ('my_distutils',
218 'MyMSVCCompiler',
219 'My MSVC derived class')
220
221
222 # make it look like it is part of the package...
223 import my_distutils
224 sys.modules['distutils.my_distutils'] = my_distutils
225
226
227
228
229 #----------------------------------------------------------------------
230 # Run SWIG the way I want it done
231
232 def run_swig(files, dir, gendir, package, USE_SWIG, force, swig_args, swig_deps=[]):
233 from distutils.file_util import copy_file
234 from distutils.dep_util import newer
235 from distutils.spawn import spawn
236
237 sources = []
238
239 for file in files:
240 basefile = os.path.splitext(file)[0]
241 i_file = os.path.join(dir, file)
242 py_file = os.path.join(dir, gendir, basefile+'.py')
243 cpp_file = os.path.join(dir, gendir, basefile+'.cpp')
244
245 sources.append(cpp_file)
246
247 if USE_SWIG:
248 for dep in swig_deps:
249 if newer(dep, py_file) or newer(dep, cpp_file):
250 force = 1
251 break
252
253 if force or newer(i_file, py_file) or newer(i_file, cpp_file):
254 # we need forward slashes here even on win32
255 cpp_file = string.join(string.split(cpp_file, '\\'), '/')
256 i_file = string.join(string.split(i_file, '\\'), '/')
257
258 cmd = ['swig'] + swig_args + ['-I'+dir, '-c', '-o', cpp_file, i_file]
259 spawn(cmd, verbose=1)
260
261 # copy the generated python file to the package directory
262 copy_file(py_file, package, update=not force, verbose=0)
263
264
265 return sources
266
267
268
269 #----------------------------------------------------------------------
270 # Update local copies of wxWindows contrib files
271
272
273 def contrib_copy_tree(src, dest, verbose=0):
274 from distutils.dir_util import mkpath, copy_tree
275
276 mkpath(dest, verbose=verbose)
277 copy_tree(src, dest, update=1, verbose=verbose)
278