@@ -63,7 +63,7 @@ def __init__ (self,
6363 # indicate their installation locations.
6464
6565 self .cc = "bcc32.exe"
66- self .link = "ilink32.exe"
66+ self .linker = "ilink32.exe"
6767 self .lib = "tlib.exe"
6868
6969 self .preprocess_options = None
@@ -73,6 +73,8 @@ def __init__ (self,
7373 self .ldflags_shared = ['/Tpd' , '/Gn' , '/q' , '/x' ]
7474 self .ldflags_shared_debug = ['/Tpd' , '/Gn' , '/q' , '/x' ]
7575 self .ldflags_static = []
76+ self .ldflags_exe = ['/Gn' , '/q' , '/x' ]
77+ self .ldflags_exe_debug = ['/Gn' , '/q' , '/x' ,'/r' ]
7678
7779
7880 # -- Worker methods ------------------------------------------------
@@ -108,16 +110,33 @@ def compile (self,
108110 if skip_sources [src ]:
109111 self .announce ("skipping %s (%s up-to-date)" % (src , obj ))
110112 else :
113+ src = os .path .normpath (src )
114+ obj = os .path .normpath (obj )
115+ self .mkpath (os .path .dirname (obj ))
116+
117+ if ext == '.res' :
118+ # This is already a binary file -- skip it.
119+ continue # the 'for' loop
120+ if ext == '.rc' :
121+ # This needs to be compiled to a .res file -- do it now.
122+ try :
123+ self .spawn (["brcc32" , "-fo" , obj , src ])
124+ except DistutilsExecError , msg :
125+ raise CompileError , msg
126+ continue # the 'for' loop
127+
128+ # The next two are both for the real compiler.
111129 if ext in self ._c_extensions :
112130 input_opt = ""
113131 elif ext in self ._cpp_extensions :
114132 input_opt = "-P"
133+ else :
134+ # Unknown file type -- no extra options. The compiler
135+ # will probably fail, but let it just in case this is a
136+ # file the compiler recognizes even if we don't.
137+ input_opt = ""
115138
116- src = os .path .normpath (src )
117- obj = os .path .normpath (obj )
118-
119139 output_opt = "-o" + obj
120- self .mkpath (os .path .dirname (obj ))
121140
122141 # Compiler command line syntax is: "bcc32 [options] file(s)".
123142 # Note that the source file names must appear at the end of
@@ -163,45 +182,20 @@ def create_static_lib (self,
163182
164183 # create_static_lib ()
165184
166-
167- def link_shared_lib (self ,
168- objects ,
169- output_libname ,
170- output_dir = None ,
171- libraries = None ,
172- library_dirs = None ,
173- runtime_library_dirs = None ,
174- export_symbols = None ,
175- debug = 0 ,
176- extra_preargs = None ,
177- extra_postargs = None ,
178- build_temp = None ):
179-
180- self .link_shared_object (objects ,
181- self .shared_library_name (output_libname ),
182- output_dir = output_dir ,
183- libraries = libraries ,
184- library_dirs = library_dirs ,
185- runtime_library_dirs = runtime_library_dirs ,
186- export_symbols = export_symbols ,
187- debug = debug ,
188- extra_preargs = extra_preargs ,
189- extra_postargs = extra_postargs ,
190- build_temp = build_temp )
191-
192185
193- def link_shared_object (self ,
194- objects ,
195- output_filename ,
196- output_dir = None ,
197- libraries = None ,
198- library_dirs = None ,
199- runtime_library_dirs = None ,
200- export_symbols = None ,
201- debug = 0 ,
202- extra_preargs = None ,
203- extra_postargs = None ,
204- build_temp = None ):
186+ def link (self ,
187+ target_desc ,
188+ objects ,
189+ output_filename ,
190+ output_dir = None ,
191+ libraries = None ,
192+ library_dirs = None ,
193+ runtime_library_dirs = None ,
194+ export_symbols = None ,
195+ debug = 0 ,
196+ extra_preargs = None ,
197+ extra_postargs = None ,
198+ build_temp = None ):
205199
206200 # XXX this ignores 'build_temp'! should follow the lead of
207201 # msvccompiler.py
@@ -213,45 +207,61 @@ def link_shared_object (self,
213207 if runtime_library_dirs :
214208 self .warn ("I don't know what to do with 'runtime_library_dirs': "
215209 + str (runtime_library_dirs ))
216-
210+
217211 if output_dir is not None :
218212 output_filename = os .path .join (output_dir , output_filename )
219213
220214 if self ._need_link (objects , output_filename ):
221215
222- if debug :
223- ld_args = self .ldflags_shared_debug [:]
216+ # Figure out linker args based on type of target.
217+ if target_desc == CCompiler .EXECUTABLE :
218+ startup_obj = 'c0w32'
219+ if debug :
220+ ld_args = self .ldflags_exe_debug [:]
221+ else :
222+ ld_args = self .ldflags_exe [:]
224223 else :
225- ld_args = self .ldflags_shared [:]
224+ startup_obj = 'c0d32'
225+ if debug :
226+ ld_args = self .ldflags_shared_debug [:]
227+ else :
228+ ld_args = self .ldflags_shared [:]
229+
226230
227231 # Create a temporary exports file for use by the linker
228- head , tail = os .path .split (output_filename )
229- modname , ext = os .path .splitext (tail )
230- temp_dir = os .path .dirname (objects [0 ]) # preserve tree structure
231- def_file = os .path .join (temp_dir , '%s.def' % modname )
232- contents = ['EXPORTS' ]
233- for sym in (export_symbols or []):
234- contents .append (' %s=_%s' % (sym , sym ))
235- self .execute (write_file , (def_file , contents ),
236- "writing %s" % def_file )
232+ if export_symbols is None :
233+ def_file = ''
234+ else :
235+ head , tail = os .path .split (output_filename )
236+ modname , ext = os .path .splitext (tail )
237+ temp_dir = os .path .dirname (objects [0 ]) # preserve tree structure
238+ def_file = os .path .join (temp_dir , '%s.def' % modname )
239+ contents = ['EXPORTS' ]
240+ for sym in (export_symbols or []):
241+ contents .append (' %s=_%s' % (sym , sym ))
242+ self .execute (write_file , (def_file , contents ),
243+ "writing %s" % def_file )
237244
238245 # Borland C++ has problems with '/' in paths
239- objects = map (os .path .normpath , objects )
240- startup_obj = 'c0d32'
241- objects .insert (0 , startup_obj )
242-
243- # either exchange python15.lib in the python libs directory against
244- # a Borland-like one, or create one with name bcpp_python15.lib
245- # there and remove the pragmas from config.h
246- libraries .append ('import32' )
247- libraries .append ('cw32mt' )
248-
249- # Start building command line flags and options.
250-
246+ objects2 = map (os .path .normpath , objects )
247+ # split objects in .obj and .res files
248+ # Borland C++ needs them at different positions in the command line
249+ objects = [startup_obj ]
250+ resources = []
251+ for file in objects2 :
252+ (base , ext ) = os .path .splitext (os .path .normcase (file ))
253+ if ext == '.res' :
254+ resources .append (file )
255+ else :
256+ objects .append (file )
257+
258+
251259 for l in library_dirs :
252260 ld_args .append ("/L%s" % os .path .normpath (l ))
253-
254- ld_args .extend (objects ) # list of object files
261+ ld_args .append ("/L." ) # we sometimes use relative paths
262+
263+ # list of object files
264+ ld_args .extend (objects )
255265
256266 # XXX the command-line syntax for Borland C++ is a bit wonky;
257267 # certain filenames are jammed together in one big string, but
@@ -263,14 +273,14 @@ def link_shared_object (self,
263273 # because 'spawn()' would quote any filenames with spaces in
264274 # them. Arghghh!. Apparently it works fine as coded...
265275
266- # name of dll file
276+ # name of dll/exe file
267277 ld_args .extend ([',' ,output_filename ])
268278 # no map file and start libraries
269279 ld_args .append (',,' )
270280
271281 for lib in libraries :
272282 # see if we find it and if there is a bcpp specific lib
273- # (bcpp_xxx .lib)
283+ # (xxx_bcpp .lib)
274284 libfile = self .find_library_file (library_dirs , lib , debug )
275285 if libfile is None :
276286 ld_args .append (lib )
@@ -279,8 +289,17 @@ def link_shared_object (self,
279289 else :
280290 # full name which prefers bcpp_xxx.lib over xxx.lib
281291 ld_args .append (libfile )
292+
293+ # some default libraries
294+ ld_args .append ('import32' )
295+ ld_args .append ('cw32mt' )
296+
282297 # def file for export symbols
283298 ld_args .extend ([',' ,def_file ])
299+ # add resource files
300+ ld_args .append (',' )
301+ ld_args .extend (resources )
302+
284303
285304 if extra_preargs :
286305 ld_args [:0 ] = extra_preargs
@@ -289,88 +308,24 @@ def link_shared_object (self,
289308
290309 self .mkpath (os .path .dirname (output_filename ))
291310 try :
292- self .spawn ([self .link ] + ld_args )
311+ self .spawn ([self .linker ] + ld_args )
293312 except DistutilsExecError , msg :
294313 raise LinkError , msg
295314
296315 else :
297316 self .announce ("skipping %s (up-to-date)" % output_filename )
298317
299- # link_shared_object ()
300-
301-
302- def link_executable (self ,
303- objects ,
304- output_progname ,
305- output_dir = None ,
306- libraries = None ,
307- library_dirs = None ,
308- runtime_library_dirs = None ,
309- debug = 0 ,
310- extra_preargs = None ,
311- extra_postargs = None ):
312-
313- (objects , output_dir ) = self ._fix_object_args (objects , output_dir )
314- (libraries , library_dirs , runtime_library_dirs ) = \
315- self ._fix_lib_args (libraries , library_dirs , runtime_library_dirs )
316-
317- if runtime_library_dirs :
318- self .warn ("I don't know what to do with 'runtime_library_dirs': "
319- + str (runtime_library_dirs ))
320-
321- lib_opts = gen_lib_options (self ,
322- library_dirs , runtime_library_dirs ,
323- libraries )
324- output_filename = output_progname + self .exe_extension
325- if output_dir is not None :
326- output_filename = os .path .join (output_dir , output_filename )
327-
328- if self ._need_link (objects , output_filename ):
329-
330- if debug :
331- ldflags = self .ldflags_shared_debug [1 :]
332- else :
333- ldflags = self .ldflags_shared [1 :]
334-
335- ld_args = ldflags + lib_opts + \
336- objects + ['/OUT:' + output_filename ]
337-
338- if extra_preargs :
339- ld_args [:0 ] = extra_preargs
340- if extra_postargs :
341- ld_args .extend (extra_postargs )
342-
343- self .mkpath (os .path .dirname (output_filename ))
344- try :
345- self .spawn ([self .link ] + ld_args )
346- except DistutilsExecError , msg :
347- raise LinkError , msg
348- else :
349- self .announce ("skipping %s (up-to-date)" % output_filename )
350-
318+ # link ()
351319
352320 # -- Miscellaneous methods -----------------------------------------
353- # These are all used by the 'gen_lib_options() function, in
354- # ccompiler.py.
355-
356- def library_dir_option (self , dir ):
357- return "-L" + dir
358-
359- def runtime_library_dir_option (self , dir ):
360- raise DistutilsPlatformError , \
361- ("don't know how to set runtime library search path "
362- "for Borland C++" )
363-
364- def library_option (self , lib ):
365- return self .library_filename (lib )
366321
367322
368323 def find_library_file (self , dirs , lib , debug = 0 ):
369324 # List of effective library names to try, in order of preference:
370- # bcpp_xxx .lib is better than xxx.lib
325+ # xxx_bcpp .lib is better than xxx.lib
371326 # and xxx_d.lib is better than xxx.lib if debug is set
372327 #
373- # The "bcpp_" prefix is to handle a Python installation for people
328+ # The "_bcpp" suffix is to handle a Python installation for people
374329 # with multiple compilers (primarily Distutils hackers, I suspect
375330 # ;-). The idea is they'd have one static library for each
376331 # compiler they care about, since (almost?) every Windows compiler
@@ -390,3 +345,31 @@ def find_library_file (self, dirs, lib, debug=0):
390345 # Oops, didn't find it in *any* of 'dirs'
391346 return None
392347
348+ # overwrite the one from CCompiler to support rc and res-files
349+ def object_filenames (self ,
350+ source_filenames ,
351+ strip_dir = 0 ,
352+ output_dir = '' ):
353+ if output_dir is None : output_dir = ''
354+ obj_names = []
355+ for src_name in source_filenames :
356+ # use normcase to make sure '.rc' is really '.rc' and not '.RC'
357+ (base , ext ) = os .path .splitext (os .path .normcase (src_name ))
358+ if ext not in (self .src_extensions + ['.rc' ,'.res' ]):
359+ raise UnknownFileError , \
360+ "unknown file type '%s' (from '%s')" % \
361+ (ext , src_name )
362+ if strip_dir :
363+ base = os .path .basename (base )
364+ if ext == '.res' :
365+ # these can go unchanged
366+ obj_names .append (os .path .join (output_dir , base + ext ))
367+ elif ext == '.rc' :
368+ # these need to be compiled to .res-files
369+ obj_names .append (os .path .join (output_dir , base + '.res' ))
370+ else :
371+ obj_names .append (os .path .join (output_dir ,
372+ base + self .obj_extension ))
373+ return obj_names
374+
375+ # object_filenames ()
0 commit comments