7
7
# This module should be kept compatible with Python 2.1.
9
__revision__ = "$Id: build_ext.py 69317 2009-02-05 22:55:00Z tarek.ziade $"
9
__revision__ = "$Id: build_ext.py 74732 2009-09-09 11:39:41Z tarek.ziade $"
11
11
import sys, os, string, re
12
12
from types import *
146
146
self.extensions = self.distribution.ext_modules
149
148
# Make sure Python's include directories (for Python.h, pyconfig.h,
150
149
# etc.) are in the include search path.
151
150
py_include = sysconfig.get_python_inc()
152
151
plat_py_include = sysconfig.get_python_inc(plat_specific=1)
153
152
if self.include_dirs is None:
154
153
self.include_dirs = self.distribution.include_dirs or []
155
if type(self.include_dirs) is StringType:
156
self.include_dirs = string.split(self.include_dirs, os.pathsep)
154
if isinstance(self.include_dirs, str):
155
self.include_dirs = self.include_dirs.split(os.pathsep)
158
157
# Put the Python "system" include dir at the end, so that
159
158
# any local include dirs take precedence.
161
160
if plat_py_include != py_include:
162
161
self.include_dirs.append(plat_py_include)
164
if type(self.libraries) is StringType:
163
if isinstance(self.libraries, str):
165
164
self.libraries = [self.libraries]
167
166
# Life is easier if we're not forever checking for None, so
252
251
# symbols can be separated with commas.
255
defines = string.split(self.define, ',')
254
defines = self.define.split(',')
256
255
self.define = map(lambda symbol: (symbol, '1'), defines)
258
257
# The option for macros to undefine is also a string from the
259
258
# option parsing, but has to be a list. Multiple symbols can also
260
259
# be separated with commas here.
262
self.undef = string.split(self.undef, ',')
261
self.undef = self.undef.split(',')
264
263
if self.swig_opts is None:
265
264
self.swig_opts = []
276
275
self.library_dirs.append(user_lib)
277
276
self.rpath.append(user_lib)
279
# finalize_options ()
284
279
from distutils.ccompiler import new_compiler
286
281
# 'self.extensions', as supplied by setup.py, is a list of
327
322
self.compiler.set_include_dirs(self.include_dirs)
328
323
if self.define is not None:
329
324
# 'define' option is a list of (name,value) tuples
330
for (name,value) in self.define:
325
for (name, value) in self.define:
331
326
self.compiler.define_macro(name, value)
332
327
if self.undef is not None:
333
328
for macro in self.undef:
344
339
# Now actually compile and link everything.
345
340
self.build_extensions()
350
def check_extensions_list (self, extensions):
342
def check_extensions_list(self, extensions):
351
343
"""Ensure that the list of extensions (presumably provided as a
352
344
command option 'extensions') is valid, i.e. it is a list of
353
345
Extension objects. We also support the old-style list of 2-tuples,
357
349
Raise DistutilsSetupError if the structure is invalid anywhere;
358
350
just returns otherwise.
360
if type(extensions) is not ListType:
352
if not isinstance(extensions, list):
361
353
raise DistutilsSetupError, \
362
354
"'ext_modules' option must be a list of Extension instances"
364
for i in range(len(extensions)):
356
for i, ext in enumerate(extensions):
366
357
if isinstance(ext, Extension):
367
358
continue # OK! (assume type-checking done
368
359
# by Extension constructor)
370
(ext_name, build_info) = ext
361
if not isinstance(ext, tuple) or len(ext) != 2:
362
raise DistutilsSetupError, \
363
("each element of 'ext_modules' option must be an "
364
"Extension instance or 2-tuple")
366
ext_name, build_info = ext
371
368
log.warn(("old-style (ext_name, build_info) tuple found in "
372
369
"ext_modules for extension '%s'"
373
370
"-- please convert to Extension instance" % ext_name))
374
if type(ext) is not TupleType and len(ext) != 2:
375
raise DistutilsSetupError, \
376
("each element of 'ext_modules' option must be an "
377
"Extension instance or 2-tuple")
379
if not (type(ext_name) is StringType and
372
if not (isinstance(ext_name, str) and
380
373
extension_name_re.match(ext_name)):
381
374
raise DistutilsSetupError, \
382
375
("first element of each tuple in 'ext_modules' "
383
376
"must be the extension name (a string)")
385
if type(build_info) is not DictionaryType:
378
if not isinstance(build_info, dict):
386
379
raise DistutilsSetupError, \
387
380
("second element of each tuple in 'ext_modules' "
388
381
"must be a dictionary (build info)")
394
387
# Easy stuff: one-to-one mapping from dict elements to
395
388
# instance attributes.
396
for key in ('include_dirs',
400
'extra_compile_args',
389
for key in ('include_dirs', 'library_dirs', 'libraries',
390
'extra_objects', 'extra_compile_args',
401
391
'extra_link_args'):
402
392
val = build_info.get(key)
403
393
if val is not None:
416
406
ext.define_macros = []
417
407
ext.undef_macros = []
418
408
for macro in macros:
419
if not (type(macro) is TupleType and
420
1 <= len(macro) <= 2):
409
if not (isinstance(macro, tuple) and len(macro) in (1, 2)):
421
410
raise DistutilsSetupError, \
422
411
("'macros' element of build info dict "
423
412
"must be 1- or 2-tuple")
458
440
for ext in self.extensions:
459
fullname = self.get_ext_fullname(ext.name)
460
outputs.append(os.path.join(self.build_lib,
461
self.get_ext_filename(fullname)))
441
outputs.append(self.get_ext_fullpath(ext.name))
466
444
def build_extensions(self):
467
445
# First, sanity-check the 'extensions' list
468
446
self.check_extensions_list(self.extensions)
479
457
"a list of source filenames") % ext.name
480
458
sources = list(sources)
482
fullname = self.get_ext_fullname(ext.name)
484
# ignore build-lib -- put the compiled extension into
485
# the source tree along with pure Python modules
487
modpath = string.split(fullname, '.')
488
package = string.join(modpath[0:-1], '.')
491
build_py = self.get_finalized_command('build_py')
492
package_dir = build_py.get_package_dir(package)
493
ext_filename = os.path.join(package_dir,
494
self.get_ext_filename(base))
496
ext_filename = os.path.join(self.build_lib,
497
self.get_ext_filename(fullname))
460
ext_path = self.get_ext_fullpath(ext.name)
498
461
depends = sources + ext.depends
499
if not (self.force or newer_group(depends, ext_filename, 'newer')):
462
if not (self.force or newer_group(depends, ext_path, 'newer')):
500
463
log.debug("skipping '%s' extension (up-to-date)", ext.name)
528
491
macros.append((undef,))
530
493
objects = self.compiler.compile(sources,
531
output_dir=self.build_temp,
533
include_dirs=ext.include_dirs,
535
extra_postargs=extra_args,
494
output_dir=self.build_temp,
496
include_dirs=ext.include_dirs,
498
extra_postargs=extra_args,
538
501
# XXX -- this is a Vile HACK!
557
520
language = ext.language or self.compiler.detect_language(sources)
559
522
self.compiler.link_shared_object(
560
objects, ext_filename,
561
524
libraries=self.get_libraries(ext),
562
525
library_dirs=ext.library_dirs,
563
526
runtime_library_dirs=ext.runtime_library_dirs,
660
623
# -- Name generators -----------------------------------------------
661
624
# (extension names, filenames, whatever)
663
def get_ext_fullname (self, ext_name):
625
def get_ext_fullpath(self, ext_name):
626
"""Returns the path of the filename for a given extension.
628
The file is located in `build_lib` or directly in the package
631
fullname = self.get_ext_fullname(ext_name)
632
modpath = fullname.split('.')
633
filename = self.get_ext_filename(modpath[-1])
636
# no further work needed
638
# build_dir/package/path/filename
639
filename = os.path.join(*modpath[:-1]+[filename])
640
return os.path.join(self.build_lib, filename)
642
# the inplace option requires to find the package directory
643
# using the build_py command for that
644
package = '.'.join(modpath[0:-1])
645
build_py = self.get_finalized_command('build_py')
646
package_dir = os.path.abspath(build_py.get_package_dir(package))
649
# package_dir/filename
650
return os.path.join(package_dir, filename)
652
def get_ext_fullname(self, ext_name):
653
"""Returns the fullname of a given extension name.
655
Adds the `package.` prefix"""
664
656
if self.package is None:
667
659
return self.package + '.' + ext_name
669
def get_ext_filename (self, ext_name):
661
def get_ext_filename(self, ext_name):
670
662
r"""Convert the name of an extension (eg. "foo.bar") into the name
671
663
of the file from which it will be loaded (eg. "foo/bar.so", or
675
666
from distutils.sysconfig import get_config_var
676
667
ext_path = string.split(ext_name, '.')
677
668
# OS/2 has an 8 character module (extension) limit :-(
689
680
provided, "init" + module_name. Only relevant on Windows, where
690
681
the .pyd file (DLL) must export the module "init" function.
693
initfunc_name = "init" + string.split(ext.name,'.')[-1]
683
initfunc_name = "init" + ext.name.split('.')[-1]
694
684
if initfunc_name not in ext.export_symbols:
695
685
ext.export_symbols.append(initfunc_name)
696
686
return ext.export_symbols