[Python-checkins] CVS: distutils/distutils/command build_ext.py,1.40,1.41
Greg Ward
python-dev@python.org
Tue, 30 May 2000 18:09:54 -0700
Update of /cvsroot/python/distutils/distutils/command
In directory slayer.i.sourceforge.net:/tmp/cvs-serv7537
Modified Files:
build_ext.py
Log Message:
Overhauled to expect 'self.extensions' (taken from 'ext_modules' in the
setup script) to be a list of Extension instances, rather than a list of of
(ext_name, build_info) tuples. This is mostly a simplification, but
'check_extension_list()' got a lot more complicated because of the need to
convert the old-style tuples to Extension instances.
Temporarily dropped support for defining/undefining macros in the
'extensions' list -- I want to change the interface, but haven't yet made
the required changes in CCompiler and friends to support this nicely.
Also neatened up the code that merges 'extra_compile_flags' and the CFLAGS
environment variable.
Index: build_ext.py
===================================================================
RCS file: /cvsroot/python/distutils/distutils/command/build_ext.py,v
retrieving revision 1.40
retrieving revision 1.41
diff -C2 -r1.40 -r1.41
*** build_ext.py 2000/05/27 17:27:23 1.40
--- build_ext.py 2000/05/31 01:09:52 1.41
***************
*** 7,11 ****
# created 1999/08/09, Greg Ward
! __revision__ = "$Id: build_ext.py,v 1.40 2000/05/27 17:27:23 gward Exp $"
import sys, os, string, re
--- 7,11 ----
# created 1999/08/09, Greg Ward
! __revision__ = "$Id: build_ext.py,v 1.41 2000/05/31 01:09:52 gward Exp $"
import sys, os, string, re
***************
*** 14,17 ****
--- 14,18 ----
from distutils.errors import *
from distutils.dep_util import newer_group
+ from distutils.extension import Extension
# An extension name is just a dot-separated list of Python NAMEs (ie.
***************
*** 153,163 ****
from distutils.ccompiler import new_compiler
! # 'self.extensions', as supplied by setup.py, is a list of 2-tuples.
! # Each tuple is simple:
# (ext_name, build_info)
! # build_info is a dictionary containing everything specific to
! # building this extension. (Info pertaining to all extensions
! # should be handled by general distutils options passed from
! # setup.py down to right here, but that's not taken care of yet.)
if not self.extensions:
--- 154,168 ----
from distutils.ccompiler import new_compiler
! # 'self.extensions', as supplied by setup.py, is a list of
! # Extension instances. See the documentation for Extension (in
! # distutils.core) for details.
! #
! # For backwards compatibility with Distutils 0.8.2 and earlier, we
! # also allow the 'extensions' list to be a list of tuples:
# (ext_name, build_info)
! # where build_info is a dictionary containing everything that
! # Extension instances do except the name, with a few things being
! # differently named. We convert these 2-tuples to Extension
! # instances as needed.
if not self.extensions:
***************
*** 209,238 ****
def check_extensions_list (self, extensions):
"""Ensure that the list of extensions (presumably provided as a
! command option 'extensions') is valid, i.e. it is a list of
! 2-tuples, where the tuples are (extension_name, build_info_dict).
! Raise DistutilsSetupError if the structure is invalid anywhere;
! just returns otherwise."""
!
! if type (extensions) is not ListType:
raise DistutilsSetupError, \
! "'ext_modules' option must be a list of tuples"
! for ext in extensions:
! if type (ext) is not TupleType and len (ext) != 2:
raise DistutilsSetupError, \
! "each element of 'ext_modules' option must be a 2-tuple"
! if not (type (ext[0]) is StringType and
! extension_name_re.match (ext[0])):
raise DistutilsSetupError, \
! "first element of each tuple in 'ext_modules' " + \
! "must be the extension name (a string)"
! if type (ext[1]) is not DictionaryType:
raise DistutilsSetupError, \
! "second element of each tuple in 'ext_modules' " + \
! "must be a dictionary (build info)"
! # end sanity-check for
# check_extensions_list ()
--- 214,293 ----
def check_extensions_list (self, extensions):
"""Ensure that the list of extensions (presumably provided as a
! command option 'extensions') is valid, i.e. it is a list of
! Extension objects. We also support the old-style list of 2-tuples,
! where the tuples are (ext_name, build_info), which are converted to
! Extension instances here.
!
! Raise DistutilsSetupError if the structure is invalid anywhere;
! just returns otherwise.
! """
! if type(extensions) is not ListType:
raise DistutilsSetupError, \
! "'ext_modules' option must be a list of Extension instances"
! for i in range(len(extensions)):
! ext = extensions[i]
! if isinstance(ext, Extension):
! continue # OK! (assume type-checking done
! # by Extension constructor)
!
! (ext_name, build_info) = ext
! self.warn(("old-style (ext_name, build_info) tuple found in "
! "ext_modules for extension '%s'"
! "-- please convert to Extension instance" % ext_name))
! if type(ext) is not TupleType and len(ext) != 2:
raise DistutilsSetupError, \
! ("each element of 'ext_modules' option must be an "
! "Extension instance or 2-tuple")
! if not (type(ext_name) is StringType and
! extension_name_re.match(ext_name)):
raise DistutilsSetupError, \
! ("first element of each tuple in 'ext_modules' "
! "must be the extension name (a string)")
! if type(build_info) is not DictionaryType:
raise DistutilsSetupError, \
! ("second element of each tuple in 'ext_modules' "
! "must be a dictionary (build info)")
!
! # OK, the (ext_name, build_info) dict is type-safe: convert it
! # to an Extension instance.
! ext = Extension(ext_name, build_info['sources'])
!
! # Easy stuff: one-to-one mapping from dict elements to
! # instance attributes.
! for key in ('include_dirs',
! 'library_dirs',
! 'libraries',
! 'extra_objects',
! 'extra_compile_args',
! 'extra_link_args'):
! setattr(ext, key, build_info.get(key))
!
! # Medium-easy stuff: same syntax/semantics, different names.
! ext.runtime_library_dirs = build_info.get('rpath')
! ext.export_symbol_file = build_info.get('def_file')
!
! # Non-trivial stuff: 'macros' split into 'define_macros'
! # and 'undef_macros'.
! macros = build_info.get('macros')
! if macros:
! ext.define_macros = []
! ext.undef_macros = []
! for macro in macros:
! if not (type(macro) is TupleType and
! 1 <= len(macros) <= 2):
! raise DistutilsSetupError, \
! ("'macros' element of build info dict "
! "must be 1- or 2-tuple")
! if len(macro) == 1:
! ext.undef_macros.append(macro[0])
! elif len(macro) == 2:
! ext.define_macros.append(macro)
!
! extensions[i] = ext
! # for extensions
# check_extensions_list ()
***************
*** 244,251 ****
# Wouldn't it be neat if we knew the names of header files too...
! for (extension_name, build_info) in self.extensions:
! sources = build_info.get ('sources')
! if type (sources) in (ListType, TupleType):
! filenames.extend (sources)
return filenames
--- 299,304 ----
# Wouldn't it be neat if we knew the names of header files too...
! for ext in self.extensions:
! filenames.extend (ext.sources)
return filenames
***************
*** 263,268 ****
# "build" tree.
outputs = []
! for (extension_name, build_info) in self.extensions:
! fullname = self.get_ext_fullname (extension_name)
outputs.append (os.path.join (self.build_lib,
self.get_ext_filename(fullname)))
--- 316,321 ----
# "build" tree.
outputs = []
! for ext in self.extensions:
! fullname = self.get_ext_fullname (ext.name)
outputs.append (os.path.join (self.build_lib,
self.get_ext_filename(fullname)))
***************
*** 277,290 ****
self.check_extensions_list (self.extensions)
! for (extension_name, build_info) in self.extensions:
! sources = build_info.get ('sources')
if sources is None or type (sources) not in (ListType, TupleType):
raise DistutilsSetupError, \
("in 'ext_modules' option (extension '%s'), " +
"'sources' must be present and must be " +
! "a list of source filenames") % extension_name
sources = list (sources)
! fullname = self.get_ext_fullname (extension_name)
if self.inplace:
# ignore build-lib -- put the compiled extension into
--- 330,343 ----
self.check_extensions_list (self.extensions)
! for ext in self.extensions:
! sources = ext.sources
if sources is None or type (sources) not in (ListType, TupleType):
raise DistutilsSetupError, \
("in 'ext_modules' option (extension '%s'), " +
"'sources' must be present and must be " +
! "a list of source filenames") % ext.name
sources = list (sources)
! fullname = self.get_ext_fullname (ext.name)
if self.inplace:
# ignore build-lib -- put the compiled extension into
***************
*** 303,312 ****
self.get_ext_filename(fullname))
! if not newer_group(sources, ext_filename, 'newer'):
self.announce ("skipping '%s' extension (up-to-date)" %
! extension_name)
continue # 'for' loop over all extensions
else:
! self.announce ("building '%s' extension" % extension_name)
# First step: compile the source code to object files. This
--- 356,365 ----
self.get_ext_filename(fullname))
! if not (self.force or newer_group(sources, ext_filename, 'newer')):
self.announce ("skipping '%s' extension (up-to-date)" %
! ext.name)
continue # 'for' loop over all extensions
else:
! self.announce ("building '%s' extension" % ext.name)
# First step: compile the source code to object files. This
***************
*** 315,333 ****
# Makefile.pre.in-based system does it, so at least there's a
# precedent!)
! macros = build_info.get ('macros')
! include_dirs = build_info.get ('include_dirs')
! extra_args = build_info.get ('extra_compile_args')
! # honor CFLAGS enviroment variable
! # XXX do we *really* need this? or is it just a hack until
! # the user can put compiler flags in setup.cfg?
if os.environ.has_key('CFLAGS'):
! if not extra_args:
! extra_args = []
! extra_args = string.split(os.environ['CFLAGS']) + extra_args
objects = self.compiler.compile (sources,
output_dir=self.build_temp,
! macros=macros,
! include_dirs=include_dirs,
debug=self.debug,
extra_postargs=extra_args)
--- 368,398 ----
# Makefile.pre.in-based system does it, so at least there's a
# precedent!)
!
! # XXX not honouring 'define_macros' or 'undef_macros' -- the
! # CCompiler API needs to change to accomodate this, and I
! # want to do one thing at a time!
!
! # Two possible sources for extra compiler arguments:
! # - 'extra_compile_args' in Extension object
! # - CFLAGS environment variable (not particularly
! # elegant, but people seem to expect it and I
! # guess it's useful)
! # The environment variable should take precedence, and
! # any sensible compiler will give precendence to later
! # command line args. Hence we combine them in order:
! extra_args = ext.extra_compile_args
!
! # XXX and if we support CFLAGS, why not CC (compiler
! # executable), CPPFLAGS (pre-processor options), and LDFLAGS
! # (linker options) too?
! # XXX should we use shlex to properly parse CFLAGS?
!
if os.environ.has_key('CFLAGS'):
! extra_args.extend(string.split(os.environ['CFLAGS']))
objects = self.compiler.compile (sources,
output_dir=self.build_temp,
! #macros=macros,
! include_dirs=ext.include_dirs,
debug=self.debug,
extra_postargs=extra_args)
***************
*** 336,346 ****
# of course, first we have to figure out all the other things
# that go into the mix.
! extra_objects = build_info.get ('extra_objects')
! if extra_objects:
! objects.extend (extra_objects)
! libraries = build_info.get ('libraries')
! library_dirs = build_info.get ('library_dirs')
! rpath = build_info.get ('rpath')
! extra_args = build_info.get ('extra_link_args') or []
# XXX this is a kludge! Knowledge of specific compilers or
--- 401,407 ----
# of course, first we have to figure out all the other things
# that go into the mix.
! if ext.extra_objects:
! objects.extend (ext.extra_objects)
! extra_args = ext.extra_link_args
# XXX this is a kludge! Knowledge of specific compilers or
***************
*** 355,362 ****
# kludges; they are to be avoided if possible!)
if self.compiler.compiler_type == 'msvc':
! def_file = build_info.get ('def_file')
if def_file is None:
source_dir = os.path.dirname (sources[0])
! ext_base = (string.split (extension_name, '.'))[-1]
def_file = os.path.join (source_dir, "%s.def" % ext_base)
if not os.path.exists (def_file):
--- 416,423 ----
# kludges; they are to be avoided if possible!)
if self.compiler.compiler_type == 'msvc':
! def_file = ext.export_symbol_file
if def_file is None:
source_dir = os.path.dirname (sources[0])
! ext_base = (string.split (ext.name, '.'))[-1]
def_file = os.path.join (source_dir, "%s.def" % ext_base)
if not os.path.exists (def_file):
***************
*** 366,370 ****
extra_args.append ('/DEF:' + def_file)
else:
! modname = string.split (extension_name, '.')[-1]
extra_args.append('/export:init%s'%modname)
--- 427,431 ----
extra_args.append ('/DEF:' + def_file)
else:
! modname = string.split (ext.name, '.')[-1]
extra_args.append('/export:init%s'%modname)
***************
*** 375,389 ****
implib_file = os.path.join (
self.build_temp,
! self.get_ext_libname (extension_name))
extra_args.append ('/IMPLIB:' + implib_file)
self.mkpath (os.path.dirname (implib_file))
# if MSVC
! self.compiler.link_shared_object (objects, ext_filename,
! libraries=libraries,
! library_dirs=library_dirs,
! runtime_library_dirs=rpath,
! extra_postargs=extra_args,
! debug=self.debug)
# build_extensions ()
--- 436,451 ----
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))
# if MSVC
! self.compiler.link_shared_object (
! objects, ext_filename,
! libraries=ext.libraries,
! library_dirs=ext.library_dirs,
! runtime_library_dirs=ext.runtime_library_dirs,
! extra_postargs=extra_args,
! debug=self.debug)
# build_extensions ()