]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/distutils/command/build_ext.py
1 """distutils.command.build_ext
3 Implements the Distutils 'build_ext' command, for building extension
4 modules (currently limited to C extensions, should accommodate C++
7 # This module should be kept compatible with Python 1.5.2.
11 import sys
, os
, string
, re
13 from distutils
.core
import Command
14 from distutils
.errors
import *
15 from distutils
.sysconfig
import customize_compiler
, get_python_version
16 from distutils
.dep_util
import newer_group
17 from distutils
.extension
import Extension
18 from distutils
import log
20 # An extension name is just a dot-separated list of Python NAMEs (ie.
21 # the same as a fully-qualified module name).
22 extension_name_re
= re
.compile \
23 (r
'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$')
26 def show_compilers ():
27 from distutils
.ccompiler
import show_compilers
31 class build_ext (Command
):
33 description
= "build C/C++ extensions (compile/link to build directory)"
35 # XXX thoughts on how to deal with complex command-line options like
36 # these, i.e. how to make it so fancy_getopt can suck them off the
37 # command line and make it look like setup.py defined the appropriate
38 # lists of tuples of what-have-you.
39 # - each command needs a callback to process its command-line options
40 # - Command.__init__() needs access to its share of the whole
41 # command line (must ultimately come from
42 # Distribution.parse_command_line())
43 # - it then calls the current command class' option-parsing
44 # callback to deal with weird options like -D, which have to
45 # parse the option text and churn out some custom data
47 # - that data structure (in this case, a list of 2-tuples)
48 # will then be present in the command object by the time
49 # we get to finalize_options() (i.e. the constructor
50 # takes care of both command-line and client options
51 # in between initialize_options() and finalize_options())
53 sep_by
= " (separated by '%s')" % os
.pathsep
56 "directory for compiled extension modules"),
58 "directory for temporary files (build by-products)"),
60 "ignore build-lib and put compiled extensions into the source " +
61 "directory alongside your pure Python modules"),
62 ('include-dirs=', 'I',
63 "list of directories to search for header files" + sep_by
),
65 "C preprocessor macros to define"),
67 "C preprocessor macros to undefine"),
69 "external C libraries to link with"),
70 ('library-dirs=', 'L',
71 "directories to search for external C libraries" + sep_by
),
73 "directories to search for shared C libraries at runtime"),
74 ('link-objects=', 'O',
75 "extra explicit link objects to include in the link"),
77 "compile/link with debugging information"),
79 "forcibly build everything (ignore file timestamps)"),
81 "specify the compiler type"),
83 "make SWIG create C++ files (default is C)"),
86 boolean_options
= ['inplace', 'debug', 'force', 'swig-cpp']
89 ('help-compiler', None,
90 "list available compilers", show_compilers
),
93 def initialize_options (self
):
94 self
.extensions
= None
96 self
.build_temp
= None
100 self
.include_dirs
= None
103 self
.libraries
= None
104 self
.library_dirs
= None
106 self
.link_objects
= None
113 def finalize_options (self
):
114 from distutils
import sysconfig
116 self
.set_undefined_options('build',
117 ('build_lib', 'build_lib'),
118 ('build_temp', 'build_temp'),
119 ('compiler', 'compiler'),
123 if self
.package
is None:
124 self
.package
= self
.distribution
.ext_package
126 self
.extensions
= self
.distribution
.ext_modules
129 # Make sure Python's include directories (for Python.h, pyconfig.h,
130 # etc.) are in the include search path.
131 py_include
= sysconfig
.get_python_inc()
132 plat_py_include
= sysconfig
.get_python_inc(plat_specific
=1)
133 if self
.include_dirs
is None:
134 self
.include_dirs
= self
.distribution
.include_dirs
or []
135 if type(self
.include_dirs
) is StringType
:
136 self
.include_dirs
= string
.split(self
.include_dirs
, os
.pathsep
)
138 # Put the Python "system" include dir at the end, so that
139 # any local include dirs take precedence.
140 self
.include_dirs
.append(py_include
)
141 if plat_py_include
!= py_include
:
142 self
.include_dirs
.append(plat_py_include
)
144 if type(self
.libraries
) is StringType
:
145 self
.libraries
= [self
.libraries
]
147 # Life is easier if we're not forever checking for None, so
148 # simplify these options to empty lists if unset
149 if self
.libraries
is None:
151 if self
.library_dirs
is None:
152 self
.library_dirs
= []
153 elif type(self
.library_dirs
) is StringType
:
154 self
.library_dirs
= string
.split(self
.library_dirs
, os
.pathsep
)
156 if self
.rpath
is None:
158 elif type(self
.rpath
) is StringType
:
159 self
.rpath
= string
.split(self
.rpath
, os
.pathsep
)
161 # for extensions under windows use different directories
162 # for Release and Debug builds.
163 # also Python's library directory must be appended to library_dirs
165 self
.library_dirs
.append(os
.path
.join(sys
.exec_prefix
, 'libs'))
167 self
.build_temp
= os
.path
.join(self
.build_temp
, "Debug")
169 self
.build_temp
= os
.path
.join(self
.build_temp
, "Release")
171 # Append the source distribution include and library directories,
172 # this allows distutils on windows to work in the source tree
173 self
.include_dirs
.append(os
.path
.join(sys
.exec_prefix
, 'PC'))
174 self
.library_dirs
.append(os
.path
.join(sys
.exec_prefix
, 'PCBuild'))
176 # OS/2 (EMX) doesn't support Debug vs Release builds, but has the
177 # import libraries in its "Config" subdirectory
179 self
.library_dirs
.append(os
.path
.join(sys
.exec_prefix
, 'Config'))
181 # for extensions under Cygwin and AtheOS Python's library directory must be
182 # appended to library_dirs
183 if sys
.platform
[:6] == 'cygwin' or sys
.platform
[:6] == 'atheos':
184 if string
.find(sys
.executable
, sys
.exec_prefix
) != -1:
185 # building third party extensions
186 self
.library_dirs
.append(os
.path
.join(sys
.prefix
, "lib",
187 "python" + get_python_version(),
190 # building python standard extensions
191 self
.library_dirs
.append('.')
193 # The argument parsing will result in self.define being a string, but
194 # it has to be a list of 2-tuples. All the preprocessor symbols
195 # specified by the 'define' option will be set to '1'. Multiple
196 # symbols can be separated with commas.
199 defines
= string
.split(self
.define
, ',')
200 self
.define
= map(lambda symbol
: (symbol
, '1'), defines
)
202 # The option for macros to undefine is also a string from the
203 # option parsing, but has to be a list. Multiple symbols can also
204 # be separated with commas here.
206 self
.undef
= string
.split(self
.undef
, ',')
208 # finalize_options ()
213 from distutils
.ccompiler
import new_compiler
215 # 'self.extensions', as supplied by setup.py, is a list of
216 # Extension instances. See the documentation for Extension (in
217 # distutils.extension) for details.
219 # For backwards compatibility with Distutils 0.8.2 and earlier, we
220 # also allow the 'extensions' list to be a list of tuples:
221 # (ext_name, build_info)
222 # where build_info is a dictionary containing everything that
223 # Extension instances do except the name, with a few things being
224 # differently named. We convert these 2-tuples to Extension
225 # instances as needed.
227 if not self
.extensions
:
230 # If we were asked to build any C/C++ libraries, make sure that the
231 # directory where we put them is in the library search path for
232 # linking extensions.
233 if self
.distribution
.has_c_libraries():
234 build_clib
= self
.get_finalized_command('build_clib')
235 self
.libraries
.extend(build_clib
.get_library_names() or [])
236 self
.library_dirs
.append(build_clib
.build_clib
)
238 # Setup the CCompiler object that we'll use to do all the
239 # compiling and linking
240 self
.compiler
= new_compiler(compiler
=self
.compiler
,
241 verbose
=self
.verbose
,
242 dry_run
=self
.dry_run
,
244 customize_compiler(self
.compiler
)
246 # And make sure that any compile/link-related options (which might
247 # come from the command-line or from the setup script) are set in
248 # that CCompiler object -- that way, they automatically apply to
249 # all compiling and linking done here.
250 if self
.include_dirs
is not None:
251 self
.compiler
.set_include_dirs(self
.include_dirs
)
252 if self
.define
is not None:
253 # 'define' option is a list of (name,value) tuples
254 for (name
,value
) in self
.define
:
255 self
.compiler
.define_macro(name
, value
)
256 if self
.undef
is not None:
257 for macro
in self
.undef
:
258 self
.compiler
.undefine_macro(macro
)
259 if self
.libraries
is not None:
260 self
.compiler
.set_libraries(self
.libraries
)
261 if self
.library_dirs
is not None:
262 self
.compiler
.set_library_dirs(self
.library_dirs
)
263 if self
.rpath
is not None:
264 self
.compiler
.set_runtime_library_dirs(self
.rpath
)
265 if self
.link_objects
is not None:
266 self
.compiler
.set_link_objects(self
.link_objects
)
268 # Now actually compile and link everything.
269 self
.build_extensions()
274 def check_extensions_list (self
, extensions
):
275 """Ensure that the list of extensions (presumably provided as a
276 command option 'extensions') is valid, i.e. it is a list of
277 Extension objects. We also support the old-style list of 2-tuples,
278 where the tuples are (ext_name, build_info), which are converted to
279 Extension instances here.
281 Raise DistutilsSetupError if the structure is invalid anywhere;
282 just returns otherwise.
284 if type(extensions
) is not ListType
:
285 raise DistutilsSetupError
, \
286 "'ext_modules' option must be a list of Extension instances"
288 for i
in range(len(extensions
)):
290 if isinstance(ext
, Extension
):
291 continue # OK! (assume type-checking done
292 # by Extension constructor)
294 (ext_name
, build_info
) = ext
295 log
.warn(("old-style (ext_name, build_info) tuple found in "
296 "ext_modules for extension '%s'"
297 "-- please convert to Extension instance" % ext_name
))
298 if type(ext
) is not TupleType
and len(ext
) != 2:
299 raise DistutilsSetupError
, \
300 ("each element of 'ext_modules' option must be an "
301 "Extension instance or 2-tuple")
303 if not (type(ext_name
) is StringType
and
304 extension_name_re
.match(ext_name
)):
305 raise DistutilsSetupError
, \
306 ("first element of each tuple in 'ext_modules' "
307 "must be the extension name (a string)")
309 if type(build_info
) is not DictionaryType
:
310 raise DistutilsSetupError
, \
311 ("second element of each tuple in 'ext_modules' "
312 "must be a dictionary (build info)")
314 # OK, the (ext_name, build_info) dict is type-safe: convert it
315 # to an Extension instance.
316 ext
= Extension(ext_name
, build_info
['sources'])
318 # Easy stuff: one-to-one mapping from dict elements to
319 # instance attributes.
320 for key
in ('include_dirs',
324 'extra_compile_args',
326 val
= build_info
.get(key
)
328 setattr(ext
, key
, val
)
330 # Medium-easy stuff: same syntax/semantics, different names.
331 ext
.runtime_library_dirs
= build_info
.get('rpath')
332 if build_info
.has_key('def_file'):
333 log
.warn("'def_file' element of build info dict "
334 "no longer supported")
336 # Non-trivial stuff: 'macros' split into 'define_macros'
337 # and 'undef_macros'.
338 macros
= build_info
.get('macros')
340 ext
.define_macros
= []
341 ext
.undef_macros
= []
343 if not (type(macro
) is TupleType
and
344 1 <= len(macro
) <= 2):
345 raise DistutilsSetupError
, \
346 ("'macros' element of build info dict "
347 "must be 1- or 2-tuple")
349 ext
.undef_macros
.append(macro
[0])
350 elif len(macro
) == 2:
351 ext
.define_macros
.append(macro
)
357 # check_extensions_list ()
360 def get_source_files (self
):
361 self
.check_extensions_list(self
.extensions
)
364 # Wouldn't it be neat if we knew the names of header files too...
365 for ext
in self
.extensions
:
366 filenames
.extend(ext
.sources
)
371 def get_outputs (self
):
373 # Sanity check the 'extensions' list -- can't assume this is being
374 # done in the same run as a 'build_extensions()' call (in fact, we
375 # can probably assume that it *isn't*!).
376 self
.check_extensions_list(self
.extensions
)
378 # And build the list of output (built) filenames. Note that this
379 # ignores the 'inplace' flag, and assumes everything goes in the
382 for ext
in self
.extensions
:
383 fullname
= self
.get_ext_fullname(ext
.name
)
384 outputs
.append(os
.path
.join(self
.build_lib
,
385 self
.get_ext_filename(fullname
)))
390 def build_extensions(self
):
391 # First, sanity-check the 'extensions' list
392 self
.check_extensions_list(self
.extensions
)
394 for ext
in self
.extensions
:
395 self
.build_extension(ext
)
397 def build_extension(self
, ext
):
398 sources
= ext
.sources
399 if sources
is None or type(sources
) not in (ListType
, TupleType
):
400 raise DistutilsSetupError
, \
401 ("in 'ext_modules' option (extension '%s'), " +
402 "'sources' must be present and must be " +
403 "a list of source filenames") % ext
.name
404 sources
= list(sources
)
406 fullname
= self
.get_ext_fullname(ext
.name
)
408 # ignore build-lib -- put the compiled extension into
409 # the source tree along with pure Python modules
411 modpath
= string
.split(fullname
, '.')
412 package
= string
.join(modpath
[0:-1], '.')
415 build_py
= self
.get_finalized_command('build_py')
416 package_dir
= build_py
.get_package_dir(package
)
417 ext_filename
= os
.path
.join(package_dir
,
418 self
.get_ext_filename(base
))
420 ext_filename
= os
.path
.join(self
.build_lib
,
421 self
.get_ext_filename(fullname
))
422 depends
= sources
+ ext
.depends
423 if not (self
.force
or newer_group(depends
, ext_filename
, 'newer')):
424 log
.debug("skipping '%s' extension (up-to-date)", ext
.name
)
427 log
.info("building '%s' extension", ext
.name
)
429 # First, scan the sources for SWIG definition files (.i), run
430 # SWIG on 'em to create .c files, and modify the sources list
432 sources
= self
.swig_sources(sources
)
434 # Next, compile the source code to object files.
436 # XXX not honouring 'define_macros' or 'undef_macros' -- the
437 # CCompiler API needs to change to accommodate this, and I
438 # want to do one thing at a time!
440 # Two possible sources for extra compiler arguments:
441 # - 'extra_compile_args' in Extension object
442 # - CFLAGS environment variable (not particularly
443 # elegant, but people seem to expect it and I
445 # The environment variable should take precedence, and
446 # any sensible compiler will give precedence to later
447 # command line args. Hence we combine them in order:
448 extra_args
= ext
.extra_compile_args
or []
450 macros
= ext
.define_macros
[:]
451 for undef
in ext
.undef_macros
:
452 macros
.append((undef
,))
454 objects
= self
.compiler
.compile(sources
,
455 output_dir
=self
.build_temp
,
457 include_dirs
=ext
.include_dirs
,
459 extra_postargs
=extra_args
,
462 # XXX -- this is a Vile HACK!
464 # The setup.py script for Python on Unix needs to be able to
465 # get this list so it can perform all the clean up needed to
466 # avoid keeping object files around when cleaning out a failed
467 # build of an extension module. Since Distutils does not
468 # track dependencies, we have to get rid of intermediates to
469 # ensure all the intermediates will be properly re-built.
471 self
._built
_objects
= objects
[:]
473 # Now link the object files together into a "shared object" --
474 # of course, first we have to figure out all the other things
475 # that go into the mix.
476 if ext
.extra_objects
:
477 objects
.extend(ext
.extra_objects
)
478 extra_args
= ext
.extra_link_args
or []
480 # Detect target language, if not provided
481 language
= ext
.language
or self
.compiler
.detect_language(sources
)
483 self
.compiler
.link_shared_object(
484 objects
, ext_filename
,
485 libraries
=self
.get_libraries(ext
),
486 library_dirs
=ext
.library_dirs
,
487 runtime_library_dirs
=ext
.runtime_library_dirs
,
488 extra_postargs
=extra_args
,
489 export_symbols
=self
.get_export_symbols(ext
),
491 build_temp
=self
.build_temp
,
492 target_lang
=language
)
495 def swig_sources (self
, sources
):
497 """Walk the list of source files in 'sources', looking for SWIG
498 interface (.i) files. Run SWIG on all that are found, and
499 return a modified 'sources' list with SWIG source files replaced
500 by the generated C (or C++) files.
507 # XXX this drops generated C/C++ files into the source tree, which
508 # is fine for developers who want to distribute the generated
509 # source -- but there should be an option to put SWIG output in
517 for source
in sources
:
518 (base
, ext
) = os
.path
.splitext(source
)
519 if ext
== ".i": # SWIG interface file
520 new_sources
.append(base
+ '_wrap' + target_ext
)
521 swig_sources
.append(source
)
522 swig_targets
[source
] = new_sources
[-1]
524 new_sources
.append(source
)
529 swig
= self
.find_swig()
530 swig_cmd
= [swig
, "-python"]
532 swig_cmd
.append("-c++")
534 for source
in swig_sources
:
535 target
= swig_targets
[source
]
536 log
.info("swigging %s to %s", source
, target
)
537 self
.spawn(swig_cmd
+ ["-o", target
, source
])
543 def find_swig (self
):
544 """Return the name of the SWIG executable. On Unix, this is
545 just "swig" -- it should be in the PATH. Tries a bit harder on
549 if os
.name
== "posix":
551 elif os
.name
== "nt":
553 # Look for SWIG in its standard installation directory on
554 # Windows (or so I presume!). If we find it there, great;
555 # if not, act like Unix and assume it's in the PATH.
556 for vers
in ("1.3", "1.2", "1.1"):
557 fn
= os
.path
.join("c:\\swig%s" % vers
, "swig.exe")
558 if os
.path
.isfile(fn
):
563 elif os
.name
== "os2":
564 # assume swig available in the PATH.
568 raise DistutilsPlatformError
, \
569 ("I don't know how to find (much less run) SWIG "
570 "on platform '%s'") % os
.name
574 # -- Name generators -----------------------------------------------
575 # (extension names, filenames, whatever)
577 def get_ext_fullname (self
, ext_name
):
578 if self
.package
is None:
581 return self
.package
+ '.' + ext_name
583 def get_ext_filename (self
, ext_name
):
584 r
"""Convert the name of an extension (eg. "foo.bar") into the name
585 of the file from which it will be loaded (eg. "foo/bar.so", or
589 from distutils
.sysconfig
import get_config_var
590 ext_path
= string
.split(ext_name
, '.')
591 # OS/2 has an 8 character module (extension) limit :-(
593 ext_path
[len(ext_path
) - 1] = ext_path
[len(ext_path
) - 1][:8]
594 # extensions in debug_mode are named 'module_d.pyd' under windows
595 so_ext
= get_config_var('SO')
596 if os
.name
== 'nt' and self
.debug
:
597 return apply(os
.path
.join
, ext_path
) + '_d' + so_ext
598 return apply(os
.path
.join
, ext_path
) + so_ext
600 def get_export_symbols (self
, ext
):
601 """Return the list of symbols that a shared extension has to
602 export. This either uses 'ext.export_symbols' or, if it's not
603 provided, "init" + module_name. Only relevant on Windows, where
604 the .pyd file (DLL) must export the module "init" function.
607 initfunc_name
= "init" + string
.split(ext
.name
,'.')[-1]
608 if initfunc_name
not in ext
.export_symbols
:
609 ext
.export_symbols
.append(initfunc_name
)
610 return ext
.export_symbols
612 def get_libraries (self
, ext
):
613 """Return the list of libraries to link against when building a
614 shared extension. On most platforms, this is just 'ext.libraries';
615 on Windows and OS/2, we add the Python library (eg. python20.dll).
617 # The python library is always needed on Windows. For MSVC, this
618 # is redundant, since the library is mentioned in a pragma in
619 # pyconfig.h that MSVC groks. The other Windows compilers all seem
620 # to need it mentioned explicitly, though, so that's what we do.
621 # Append '_d' to the python import library on debug builds.
622 if sys
.platform
== "win32":
623 from distutils
.msvccompiler
import MSVCCompiler
624 if not isinstance(self
.compiler
, MSVCCompiler
):
625 template
= "python%d%d"
627 template
= template
+ '_d'
628 pythonlib
= (template
%
629 (sys
.hexversion
>> 24, (sys
.hexversion
>> 16) & 0xff))
630 # don't extend ext.libraries, it may be shared with other
631 # extensions, it is a reference to the original list
632 return ext
.libraries
+ [pythonlib
]
635 elif sys
.platform
== "os2emx":
636 # EMX/GCC requires the python library explicitly, and I
637 # believe VACPP does as well (though not confirmed) - AIM Apr01
638 template
= "python%d%d"
639 # debug versions of the main DLL aren't supported, at least
640 # not at this time - AIM Apr01
642 # template = template + '_d'
643 pythonlib
= (template
%
644 (sys
.hexversion
>> 24, (sys
.hexversion
>> 16) & 0xff))
645 # don't extend ext.libraries, it may be shared with other
646 # extensions, it is a reference to the original list
647 return ext
.libraries
+ [pythonlib
]
648 elif sys
.platform
[:6] == "cygwin":
649 template
= "python%d.%d"
650 pythonlib
= (template
%
651 (sys
.hexversion
>> 24, (sys
.hexversion
>> 16) & 0xff))
652 # don't extend ext.libraries, it may be shared with other
653 # extensions, it is a reference to the original list
654 return ext
.libraries
+ [pythonlib
]
655 elif sys
.platform
[:6] == "atheos":
656 from distutils
import sysconfig
658 template
= "python%d.%d"
659 pythonlib
= (template
%
660 (sys
.hexversion
>> 24, (sys
.hexversion
>> 16) & 0xff))
661 # Get SHLIBS from Makefile
663 for lib
in sysconfig
.get_config_var('SHLIBS').split():
664 if lib
.startswith('-l'):
665 extra
.append(lib
[2:])
668 # don't extend ext.libraries, it may be shared with other
669 # extensions, it is a reference to the original list
670 return ext
.libraries
+ [pythonlib
, "m"] + extra