Index: ccompiler.py =================================================================== RCS file: /cvsroot/python/distutils/distutils/ccompiler.py,v retrieving revision 1.22 diff -c -r1.22 ccompiler.py *** ccompiler.py 2000/06/07 03:00:05 1.22 --- ccompiler.py 2000/06/16 18:05:42 *************** *** 655,660 **** --- 655,664 ---- for src_name in source_filenames: (base, ext) = os.path.splitext (src_name) if ext not in self.src_extensions: + # if extension unknown, return it as object name + # and assume someone other (maybe the linker) + # can use it. + obj_names.append (src_name) continue if strip_dir: base = os.path.basename (base) Index: msvccompiler.py =================================================================== RCS file: /cvsroot/python/distutils/distutils/msvccompiler.py,v retrieving revision 1.30 diff -c -r1.30 msvccompiler.py *** msvccompiler.py 2000/05/30 02:02:49 1.30 --- msvccompiler.py 2000/06/16 18:05:43 *************** *** 170,179 **** # Private class data (need to distinguish C from C++ source for compiler) _c_extensions = ['.c'] _cpp_extensions = ['.cc','.cpp'] # Needed for the filename generation methods provided by the # base class, CCompiler. ! src_extensions = _c_extensions + _cpp_extensions obj_extension = '.obj' static_lib_extension = '.lib' shared_lib_extension = '.dll' --- 170,182 ---- # Private class data (need to distinguish C from C++ source for compiler) _c_extensions = ['.c'] _cpp_extensions = ['.cc','.cpp'] + _rc_extensions = ['.rc'] + _mc_extensions = ['.mc'] # Needed for the filename generation methods provided by the # base class, CCompiler. ! src_extensions = _c_extensions + _cpp_extensions + _rc_extensions + _mc_extensions ! res_extension = '.res' obj_extension = '.obj' static_lib_extension = '.lib' shared_lib_extension = '.dll' *************** *** 195,200 **** --- 198,205 ---- self.cc = find_exe("cl.exe", version) self.link = find_exe("link.exe", version) self.lib = find_exe("lib.exe", version) + self.rc = find_exe("rc.exe", version) # resource compiler + self.mc = find_exe("mc.exe", version) # message compiler set_path_env_var ('lib', version) set_path_env_var ('include', version) path=get_msvc_paths('path', version) *************** *** 209,214 **** --- 214,221 ---- self.cc = "cl.exe" self.link = "link.exe" self.lib = "lib.exe" + self.rc = "rc.exe" + self.mc = "mc.exe" self.preprocess_options = None self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3' ] *************** *** 223,228 **** --- 230,266 ---- # -- Worker methods ------------------------------------------------ + def object_filenames (self, + source_filenames, + strip_dir=0, + output_dir=''): + # Copied from ccompiler.py, extended to return .res as 'object'-file + # for .rc input file + if output_dir is None: output_dir = '' + obj_names = [] + for src_name in source_filenames: + (base, ext) = os.path.splitext (src_name) + if ext not in self.src_extensions: + # Better to raise an exception instead of silently continuing + # and later complain about sources and targets having + # different lengths + raise CompileError ("Don't know how to compile %s" % src_name) + if strip_dir: + base = os.path.basename (base) + if ext in self._rc_extensions: + obj_names.append (os.path.join (output_dir, + base + self.res_extension)) + elif ext in self._mc_extensions: + obj_names.append (os.path.join (output_dir, + base + self.res_extension)) + else: + obj_names.append (os.path.join (output_dir, + base + self.obj_extension)) + return obj_names + + # object_filenames () + + def compile (self, sources, output_dir=None, *************** *** 254,267 **** if skip_sources[src]: self.announce ("skipping %s (%s up-to-date)" % (src, obj)) else: if ext in self._c_extensions: input_opt = "/Tc" + src elif ext in self._cpp_extensions: input_opt = "/Tp" + src output_opt = "/Fo" + obj - - self.mkpath (os.path.dirname (obj)) try: self.spawn ([self.cc] + compile_opts + pp_opts + [input_opt, output_opt] + --- 292,345 ---- if skip_sources[src]: self.announce ("skipping %s (%s up-to-date)" % (src, obj)) else: + self.mkpath (os.path.dirname (obj)) + if ext in self._c_extensions: input_opt = "/Tc" + src elif ext in self._cpp_extensions: input_opt = "/Tp" + src + elif ext in self._rc_extensions: + # compile .RC to .RES file + input_opt = src + output_opt = "/fo" + obj + try: + self.spawn ([self.rc] + + [output_opt] + [input_opt]) + except DistutilsExecError, msg: + raise CompileError, msg + continue + elif ext in self._mc_extensions: + # compile .MC to .RC file to .RES file + # '-h dir' specifies the directory for the generated include file + # '-r dir' specifies the target directory of the generated RC file + # and the binary message resource it includes. + + # For now (since there are no options to change this), + # we use the source-directory for the include file + # and the build directory for the RC file + # and message resources. This works at least for win32all. + h_dir = os.path.dirname (src) + rc_dir = os.path.dirname (obj) + try: + # first compile .MC to .RC and .H file + self.spawn ([self.mc] + + ['-h', h_dir, '-r', rc_dir] + [src]) + base, _ = os.path.splitext (os.path.basename (src)) + rc_file = os.path.join (rc_dir, base + '.rc') + # then compile .RC to .RES file + self.spawn ([self.rc] + + ["/fo" + obj] + [rc_file]) + + except DistutilsExecError, msg: + raise CompileError, msg + continue + else: + # how to handle this file? + raise CompileError ( + "Don't know how to compile %s to %s" % \ + (src, obj)) output_opt = "/Fo" + obj try: self.spawn ([self.cc] + compile_opts + pp_opts + [input_opt, output_opt] + *************** *** 374,382 **** if extra_postargs: ld_args.extend (extra_postargs) - print "link_shared_object():" - print " output_filename =", output_filename - print " mkpath'ing:", os.path.dirname (output_filename) self.mkpath (os.path.dirname (output_filename)) try: self.spawn ([self.link] + ld_args) --- 452,457 ---- Index: unixccompiler.py =================================================================== RCS file: /cvsroot/python/distutils/distutils/unixccompiler.py,v retrieving revision 1.25 diff -c -r1.25 unixccompiler.py *** unixccompiler.py 2000/05/30 02:02:49 1.25 --- unixccompiler.py 2000/06/16 18:05:43 *************** *** 131,136 **** --- 131,139 ---- # '_prep_compile()'. for i in range (len (sources)): src = sources[i] ; obj = objects[i] + if src == obj: + # this is probably already an object file + continue if skip_sources[src]: self.announce ("skipping %s (%s up-to-date)" % (src, obj)) else: Index: command/build_ext.py =================================================================== RCS file: /cvsroot/python/distutils/distutils/command/build_ext.py,v retrieving revision 1.42 diff -c -r1.42 build_ext.py *** command/build_ext.py 2000/06/07 03:00:06 1.42 --- command/build_ext.py 2000/06/16 18:05:44 *************** *** 147,152 **** --- 147,153 ---- # also Python's library directory must be appended to library_dirs if os.name == 'nt': self.library_dirs.append (os.path.join(sys.exec_prefix, 'libs')) + self.build_implib = self.build_temp if self.debug: self.build_temp = os.path.join (self.build_temp, "Debug") else: *************** *** 157,162 **** --- 158,164 ---- def run (self): from distutils.ccompiler import new_compiler + from distutils.swig import Swig # 'self.extensions', as supplied by setup.py, is a list of # Extension instances. See the documentation for Extension (in *************** *** 173,178 **** --- 175,185 ---- if not self.extensions: return + # Setup a swig object to use + self.swig = Swig(verbose=self.verbose, + dry_run=self.dry_run, + force=self.force) + # If we were asked to build any C/C++ libraries, make sure that the # directory where we put them is in the library search path for # linking extensions. *************** *** 366,373 **** continue # 'for' loop over all extensions else: self.announce ("building '%s' extension" % ext.name) ! # First step: compile the source code to object files. This # drops the object files in the current directory, regardless # of where the source is (may be a bad thing, but that's how a # Makefile.pre.in-based system does it, so at least there's a --- 373,387 ---- continue # 'for' loop over all extensions else: self.announce ("building '%s' extension" % ext.name) + + # First step: Pass all sources to swig, let swig generate files + # as needed, and return a list of files to pass to the compiler + sources = self.swig.compile (sources, + output_dir=self.build_temp, + #macros=macros, + include_dirs=ext.include_dirs) ! # Second step: compile the source code to object files. This # drops the object files in the current directory, regardless # of where the source is (may be a bad thing, but that's how a # Makefile.pre.in-based system does it, so at least there's a *************** *** 434,445 **** modname = string.split (ext.name, '.')[-1] extra_args.append('/export:init%s'%modname) ! # The MSVC linker generates unneeded .lib and .exp files, ! # which cannot be suppressed by any linker switches. So ! # make sure they are generated in the temporary build ! # directory. implib_file = os.path.join ( ! self.build_temp, self.get_ext_libname (ext.name)) extra_args.append ('/IMPLIB:' + implib_file) self.mkpath (os.path.dirname (implib_file)) --- 448,461 ---- modname = string.split (ext.name, '.')[-1] extra_args.append('/export:init%s'%modname) ! # The MSVC linker generates .lib and .exp files, ! # which cannot be suppressed by any linker switches. The .lib ! # files may even be needed! Make sure they are generated in ! # the temporary build directory. Since they have different ! # names for debug and release builds, they can go ! # into the same directory. implib_file = os.path.join ( ! self.build_implib, self.get_ext_libname (ext.name)) extra_args.append ('/IMPLIB:' + implib_file) self.mkpath (os.path.dirname (implib_file))