[Distutils] install w/o build, spaces in directory names
Thomas Heller
thomas.heller@ion-tof.com
Fri, 11 Feb 2000 14:20:23 +0100
From: David Ascher <DavidA@ActiveState.com>
Sent: Thursday, February 10, 2000 8:50 PM
> 2) Again on Windows, if I do
>
> python setup.py build
> python setup.py install
>
> the second line causes the code to be recompiled, even though the
> compilation is not needed. Greg assures me that that is not the case on
> Unix. Anyone have the time to tackle this?
I have patched msvccompiler.py to do this (patch is at the end).
The problem is that this is currently not safe because of the debug
flag recently introduced.
If you do
setup.py build_ext
setup.py install
everything will be fine (non-debug extensions will be compiled, linked
and installed), if after that you do
setup.py build_ext --debug
setup.py install
the debug extensions mod_d.pyd will be linked from obj-files
compiled with the wrong flags.
The only thing you can do currently is to force a rebuild with:
setup.py build_ext --debug --force
setup.py install
This should either be fixed by:
- compiling the debug and non-debug object-files into different
directories (temp-release, temp-debug)
- naming the object files differently (mod.obj vs mod_d.obj).
Thomas Heller
*** c:\python.org\distutils\distutils\msvccompiler.py Fri Feb 11 11:56:18
2000
--- distutils\msvccompiler.py Fri Feb 11 12:08:54 2000
***************
*** 14,19 ****
--- 14,21 ----
from distutils.errors import *
from distutils.ccompiler import \
CCompiler, gen_preprocess_options, gen_lib_options
+ from util import move_file, newer_pairwise, newer_group
+ from copy import copy
def get_devstudio_versions ():
***************
*** 222,239 ****
compile_options = self.compile_options_debug
else:
compile_options = self.compile_options
-
- for srcFile in sources:
- base,ext = os.path.splitext(srcFile)
- objFile = base + ".obj"
if ext in self._c_extensions:
fileOpt = "/Tc"
elif ext in self._cpp_extensions:
fileOpt = "/Tp"
! inputOpt = fileOpt + srcFile
! outputOpt = "/Fo" + objFile
cc_args = compile_options + \
base_pp_opts + \
--- 223,261 ----
compile_options = self.compile_options_debug
else:
compile_options = self.compile_options
+ # So we can mangle 'sources' without hurting the caller's data
+ orig_sources = sources
+ sources = copy (sources)
+
+ # Get the list of expected output (object) files and drop files we
+ # don't have to recompile. (Simplistic check -- we just compare
the
+ # source and object file, no deep dependency checking involving
+ # header files. Hmmm.)
+ objects = self.object_filenames (sources, output_dir=output_dir)
+
+ if not self.force:
+ skipped = newer_pairwise (sources, objects)
+ for skipped_pair in skipped:
+ self.announce ("skipping %s (%s up-to-date)" %
skipped_pair)
+
+ # Build list of (source,object) tuples for convenience
+ srcobj = []
+ for i in range (len (sources)):
+ srcobj.append ((sources[i], objects[i]))
+
+ # Compile all source files that weren't eliminated by
+ # 'newer_pairwise()'.
+
+ for (source,object) in srcobj:
+ base, ext = os.path.splitext (source)
if ext in self._c_extensions:
fileOpt = "/Tc"
elif ext in self._cpp_extensions:
fileOpt = "/Tp"
! inputOpt = fileOpt + source
! outputOpt = "/Fo" + object
cc_args = compile_options + \
base_pp_opts + \
***************
*** 245,252 ****
cc_args.extend (extra_postargs)
self.spawn ([self.cc] + cc_args)
! objectFiles.append( objFile )
! return objectFiles
# XXX the signature of this method is different from CCompiler and
--- 267,277 ----
cc_args.extend (extra_postargs)
self.spawn ([self.cc] + cc_args)
! # Have to re-fetch list of object filenames, because we want to
! # return *all* of them, including those that weren't recompiled on
! # this call!
! return self.object_filenames (orig_sources, output_dir)
! ## return self.object_filenames (orig_sources)
# XXX the signature of this method is different from CCompiler and
***************
*** 344,352 ****
if extra_postargs:
ld_args.extend (extra_postargs)
! self.spawn ( [ self.link ] + ld_args )
# -- Filename mangling methods -------------------------------------
def _change_extensions( self, filenames, newExtension ):
--- 369,391 ----
if extra_postargs:
ld_args.extend (extra_postargs)
! # If any of the input object files are newer than the output
shared
! # object, relink. Again, this is a simplistic dependency check:
! # doesn't look at any of the libraries we might be linking with.
+ if not self.force:
+ if self.dry_run:
+ newer = newer_group (objects, output_filename,
missing='newer')
+ else:
+ newer = newer_group (objects, output_filename)
+ if self.force or newer:
+ self.spawn ( [ self.link ] + ld_args )
+ else:
+ self.announce ("skipping %s (up-to-date)" % output_filename)
+
+
+
# -- Filename mangling methods -------------------------------------
def _change_extensions( self, filenames, newExtension ):
***************
*** 359,367 ****
return object_filenames
! def object_filenames (self, source_filenames):
"""Return the list of object filenames corresponding to each
specified source filename."""
return self._change_extensions( source_filenames, self._obj_ext )
def shared_object_filename (self, source_filename):
--- 398,407 ----
return object_filenames
! def object_filenames (self, source_filenames, output_dir=None):
"""Return the list of object filenames corresponding to each
specified source filename."""
+ #XXX output_dir currently ignored
return self._change_extensions( source_filenames, self._obj_ext )
def shared_object_filename (self, source_filename):