comparison venv/lib/python2.7/site-packages/setuptools/command/build_ext.py @ 0:d67268158946 draft

planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
author bcclaywell
date Mon, 12 Oct 2015 17:43:33 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:d67268158946
1 from distutils.command.build_ext import build_ext as _du_build_ext
2 from distutils.file_util import copy_file
3 from distutils.ccompiler import new_compiler
4 from distutils.sysconfig import customize_compiler
5 from distutils.errors import DistutilsError
6 from distutils import log
7 import os
8 import sys
9 import itertools
10
11 from setuptools.extension import Library
12
13 try:
14 # Attempt to use Pyrex for building extensions, if available
15 from Pyrex.Distutils.build_ext import build_ext as _build_ext
16 except ImportError:
17 _build_ext = _du_build_ext
18
19 try:
20 # Python 2.7 or >=3.2
21 from sysconfig import _CONFIG_VARS
22 except ImportError:
23 from distutils.sysconfig import get_config_var
24
25 get_config_var("LDSHARED") # make sure _config_vars is initialized
26 del get_config_var
27 from distutils.sysconfig import _config_vars as _CONFIG_VARS
28
29 have_rtld = False
30 use_stubs = False
31 libtype = 'shared'
32
33 if sys.platform == "darwin":
34 use_stubs = True
35 elif os.name != 'nt':
36 try:
37 import dl
38 use_stubs = have_rtld = hasattr(dl, 'RTLD_NOW')
39 except ImportError:
40 pass
41
42
43 if_dl = lambda s: s if have_rtld else ''
44
45
46 class build_ext(_build_ext):
47 def run(self):
48 """Build extensions in build directory, then copy if --inplace"""
49 old_inplace, self.inplace = self.inplace, 0
50 _build_ext.run(self)
51 self.inplace = old_inplace
52 if old_inplace:
53 self.copy_extensions_to_source()
54
55 def copy_extensions_to_source(self):
56 build_py = self.get_finalized_command('build_py')
57 for ext in self.extensions:
58 fullname = self.get_ext_fullname(ext.name)
59 filename = self.get_ext_filename(fullname)
60 modpath = fullname.split('.')
61 package = '.'.join(modpath[:-1])
62 package_dir = build_py.get_package_dir(package)
63 dest_filename = os.path.join(package_dir,
64 os.path.basename(filename))
65 src_filename = os.path.join(self.build_lib, filename)
66
67 # Always copy, even if source is older than destination, to ensure
68 # that the right extensions for the current Python/platform are
69 # used.
70 copy_file(
71 src_filename, dest_filename, verbose=self.verbose,
72 dry_run=self.dry_run
73 )
74 if ext._needs_stub:
75 self.write_stub(package_dir or os.curdir, ext, True)
76
77 if _build_ext is not _du_build_ext and not hasattr(_build_ext,
78 'pyrex_sources'):
79 # Workaround for problems using some Pyrex versions w/SWIG and/or 2.4
80 def swig_sources(self, sources, *otherargs):
81 # first do any Pyrex processing
82 sources = _build_ext.swig_sources(self, sources) or sources
83 # Then do any actual SWIG stuff on the remainder
84 return _du_build_ext.swig_sources(self, sources, *otherargs)
85
86 def get_ext_filename(self, fullname):
87 filename = _build_ext.get_ext_filename(self, fullname)
88 if fullname in self.ext_map:
89 ext = self.ext_map[fullname]
90 if isinstance(ext, Library):
91 fn, ext = os.path.splitext(filename)
92 return self.shlib_compiler.library_filename(fn, libtype)
93 elif use_stubs and ext._links_to_dynamic:
94 d, fn = os.path.split(filename)
95 return os.path.join(d, 'dl-' + fn)
96 return filename
97
98 def initialize_options(self):
99 _build_ext.initialize_options(self)
100 self.shlib_compiler = None
101 self.shlibs = []
102 self.ext_map = {}
103
104 def finalize_options(self):
105 _build_ext.finalize_options(self)
106 self.extensions = self.extensions or []
107 self.check_extensions_list(self.extensions)
108 self.shlibs = [ext for ext in self.extensions
109 if isinstance(ext, Library)]
110 if self.shlibs:
111 self.setup_shlib_compiler()
112 for ext in self.extensions:
113 ext._full_name = self.get_ext_fullname(ext.name)
114 for ext in self.extensions:
115 fullname = ext._full_name
116 self.ext_map[fullname] = ext
117
118 # distutils 3.1 will also ask for module names
119 # XXX what to do with conflicts?
120 self.ext_map[fullname.split('.')[-1]] = ext
121
122 ltd = self.shlibs and self.links_to_dynamic(ext) or False
123 ns = ltd and use_stubs and not isinstance(ext, Library)
124 ext._links_to_dynamic = ltd
125 ext._needs_stub = ns
126 filename = ext._file_name = self.get_ext_filename(fullname)
127 libdir = os.path.dirname(os.path.join(self.build_lib, filename))
128 if ltd and libdir not in ext.library_dirs:
129 ext.library_dirs.append(libdir)
130 if ltd and use_stubs and os.curdir not in ext.runtime_library_dirs:
131 ext.runtime_library_dirs.append(os.curdir)
132
133 def setup_shlib_compiler(self):
134 compiler = self.shlib_compiler = new_compiler(
135 compiler=self.compiler, dry_run=self.dry_run, force=self.force
136 )
137 if sys.platform == "darwin":
138 tmp = _CONFIG_VARS.copy()
139 try:
140 # XXX Help! I don't have any idea whether these are right...
141 _CONFIG_VARS['LDSHARED'] = (
142 "gcc -Wl,-x -dynamiclib -undefined dynamic_lookup")
143 _CONFIG_VARS['CCSHARED'] = " -dynamiclib"
144 _CONFIG_VARS['SO'] = ".dylib"
145 customize_compiler(compiler)
146 finally:
147 _CONFIG_VARS.clear()
148 _CONFIG_VARS.update(tmp)
149 else:
150 customize_compiler(compiler)
151
152 if self.include_dirs is not None:
153 compiler.set_include_dirs(self.include_dirs)
154 if self.define is not None:
155 # 'define' option is a list of (name,value) tuples
156 for (name, value) in self.define:
157 compiler.define_macro(name, value)
158 if self.undef is not None:
159 for macro in self.undef:
160 compiler.undefine_macro(macro)
161 if self.libraries is not None:
162 compiler.set_libraries(self.libraries)
163 if self.library_dirs is not None:
164 compiler.set_library_dirs(self.library_dirs)
165 if self.rpath is not None:
166 compiler.set_runtime_library_dirs(self.rpath)
167 if self.link_objects is not None:
168 compiler.set_link_objects(self.link_objects)
169
170 # hack so distutils' build_extension() builds a library instead
171 compiler.link_shared_object = link_shared_object.__get__(compiler)
172
173 def get_export_symbols(self, ext):
174 if isinstance(ext, Library):
175 return ext.export_symbols
176 return _build_ext.get_export_symbols(self, ext)
177
178 def build_extension(self, ext):
179 _compiler = self.compiler
180 try:
181 if isinstance(ext, Library):
182 self.compiler = self.shlib_compiler
183 _build_ext.build_extension(self, ext)
184 if ext._needs_stub:
185 cmd = self.get_finalized_command('build_py').build_lib
186 self.write_stub(cmd, ext)
187 finally:
188 self.compiler = _compiler
189
190 def links_to_dynamic(self, ext):
191 """Return true if 'ext' links to a dynamic lib in the same package"""
192 # XXX this should check to ensure the lib is actually being built
193 # XXX as dynamic, and not just using a locally-found version or a
194 # XXX static-compiled version
195 libnames = dict.fromkeys([lib._full_name for lib in self.shlibs])
196 pkg = '.'.join(ext._full_name.split('.')[:-1] + [''])
197 return any(pkg + libname in libnames for libname in ext.libraries)
198
199 def get_outputs(self):
200 return _build_ext.get_outputs(self) + self.__get_stubs_outputs()
201
202 def __get_stubs_outputs(self):
203 # assemble the base name for each extension that needs a stub
204 ns_ext_bases = (
205 os.path.join(self.build_lib, *ext._full_name.split('.'))
206 for ext in self.extensions
207 if ext._needs_stub
208 )
209 # pair each base with the extension
210 pairs = itertools.product(ns_ext_bases, self.__get_output_extensions())
211 return list(base + fnext for base, fnext in pairs)
212
213 def __get_output_extensions(self):
214 yield '.py'
215 yield '.pyc'
216 if self.get_finalized_command('build_py').optimize:
217 yield '.pyo'
218
219 def write_stub(self, output_dir, ext, compile=False):
220 log.info("writing stub loader for %s to %s", ext._full_name,
221 output_dir)
222 stub_file = (os.path.join(output_dir, *ext._full_name.split('.')) +
223 '.py')
224 if compile and os.path.exists(stub_file):
225 raise DistutilsError(stub_file + " already exists! Please delete.")
226 if not self.dry_run:
227 f = open(stub_file, 'w')
228 f.write(
229 '\n'.join([
230 "def __bootstrap__():",
231 " global __bootstrap__, __file__, __loader__",
232 " import sys, os, pkg_resources, imp" + if_dl(", dl"),
233 " __file__ = pkg_resources.resource_filename"
234 "(__name__,%r)"
235 % os.path.basename(ext._file_name),
236 " del __bootstrap__",
237 " if '__loader__' in globals():",
238 " del __loader__",
239 if_dl(" old_flags = sys.getdlopenflags()"),
240 " old_dir = os.getcwd()",
241 " try:",
242 " os.chdir(os.path.dirname(__file__))",
243 if_dl(" sys.setdlopenflags(dl.RTLD_NOW)"),
244 " imp.load_dynamic(__name__,__file__)",
245 " finally:",
246 if_dl(" sys.setdlopenflags(old_flags)"),
247 " os.chdir(old_dir)",
248 "__bootstrap__()",
249 "" # terminal \n
250 ])
251 )
252 f.close()
253 if compile:
254 from distutils.util import byte_compile
255
256 byte_compile([stub_file], optimize=0,
257 force=True, dry_run=self.dry_run)
258 optimize = self.get_finalized_command('install_lib').optimize
259 if optimize > 0:
260 byte_compile([stub_file], optimize=optimize,
261 force=True, dry_run=self.dry_run)
262 if os.path.exists(stub_file) and not self.dry_run:
263 os.unlink(stub_file)
264
265
266 if use_stubs or os.name == 'nt':
267 # Build shared libraries
268 #
269 def link_shared_object(
270 self, objects, output_libname, output_dir=None, libraries=None,
271 library_dirs=None, runtime_library_dirs=None, export_symbols=None,
272 debug=0, extra_preargs=None, extra_postargs=None, build_temp=None,
273 target_lang=None):
274 self.link(
275 self.SHARED_LIBRARY, objects, output_libname,
276 output_dir, libraries, library_dirs, runtime_library_dirs,
277 export_symbols, debug, extra_preargs, extra_postargs,
278 build_temp, target_lang
279 )
280 else:
281 # Build static libraries everywhere else
282 libtype = 'static'
283
284 def link_shared_object(
285 self, objects, output_libname, output_dir=None, libraries=None,
286 library_dirs=None, runtime_library_dirs=None, export_symbols=None,
287 debug=0, extra_preargs=None, extra_postargs=None, build_temp=None,
288 target_lang=None):
289 # XXX we need to either disallow these attrs on Library instances,
290 # or warn/abort here if set, or something...
291 # libraries=None, library_dirs=None, runtime_library_dirs=None,
292 # export_symbols=None, extra_preargs=None, extra_postargs=None,
293 # build_temp=None
294
295 assert output_dir is None # distutils build_ext doesn't pass this
296 output_dir, filename = os.path.split(output_libname)
297 basename, ext = os.path.splitext(filename)
298 if self.library_filename("x").startswith('lib'):
299 # strip 'lib' prefix; this is kludgy if some platform uses
300 # a different prefix
301 basename = basename[3:]
302
303 self.create_static_lib(
304 objects, basename, output_dir, debug, target_lang
305 )