Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: recipe_engine/third_party/setuptools/command/build_ext.py

Issue 1344583003: Recipe package system. (Closed) Base URL: git@github.com:luci/recipes-py.git@master
Patch Set: Recompiled proto Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
10 from setuptools.extension import Library
11
12 try:
13 # Attempt to use Pyrex for building extensions, if available
14 from Pyrex.Distutils.build_ext import build_ext as _build_ext
15 except ImportError:
16 _build_ext = _du_build_ext
17
18 try:
19 # Python 2.7 or >=3.2
20 from sysconfig import _CONFIG_VARS
21 except ImportError:
22 from distutils.sysconfig import get_config_var
23
24 get_config_var("LDSHARED") # make sure _config_vars is initialized
25 del get_config_var
26 from distutils.sysconfig import _config_vars as _CONFIG_VARS
27
28 have_rtld = False
29 use_stubs = False
30 libtype = 'shared'
31
32 if sys.platform == "darwin":
33 use_stubs = True
34 elif os.name != 'nt':
35 try:
36 from dl import RTLD_NOW
37
38 have_rtld = True
39 use_stubs = True
40 except ImportError:
41 pass
42
43
44 def if_dl(s):
45 if have_rtld:
46 return s
47 return ''
48
49
50 class build_ext(_build_ext):
51 def run(self):
52 """Build extensions in build directory, then copy if --inplace"""
53 old_inplace, self.inplace = self.inplace, 0
54 _build_ext.run(self)
55 self.inplace = old_inplace
56 if old_inplace:
57 self.copy_extensions_to_source()
58
59 def copy_extensions_to_source(self):
60 build_py = self.get_finalized_command('build_py')
61 for ext in self.extensions:
62 fullname = self.get_ext_fullname(ext.name)
63 filename = self.get_ext_filename(fullname)
64 modpath = fullname.split('.')
65 package = '.'.join(modpath[:-1])
66 package_dir = build_py.get_package_dir(package)
67 dest_filename = os.path.join(package_dir,
68 os.path.basename(filename))
69 src_filename = os.path.join(self.build_lib, filename)
70
71 # Always copy, even if source is older than destination, to ensure
72 # that the right extensions for the current Python/platform are
73 # used.
74 copy_file(
75 src_filename, dest_filename, verbose=self.verbose,
76 dry_run=self.dry_run
77 )
78 if ext._needs_stub:
79 self.write_stub(package_dir or os.curdir, ext, True)
80
81 if _build_ext is not _du_build_ext and not hasattr(_build_ext,
82 'pyrex_sources'):
83 # Workaround for problems using some Pyrex versions w/SWIG and/or 2.4
84 def swig_sources(self, sources, *otherargs):
85 # first do any Pyrex processing
86 sources = _build_ext.swig_sources(self, sources) or sources
87 # Then do any actual SWIG stuff on the remainder
88 return _du_build_ext.swig_sources(self, sources, *otherargs)
89
90 def get_ext_filename(self, fullname):
91 filename = _build_ext.get_ext_filename(self, fullname)
92 if fullname in self.ext_map:
93 ext = self.ext_map[fullname]
94 if isinstance(ext, Library):
95 fn, ext = os.path.splitext(filename)
96 return self.shlib_compiler.library_filename(fn, libtype)
97 elif use_stubs and ext._links_to_dynamic:
98 d, fn = os.path.split(filename)
99 return os.path.join(d, 'dl-' + fn)
100 return filename
101
102 def initialize_options(self):
103 _build_ext.initialize_options(self)
104 self.shlib_compiler = None
105 self.shlibs = []
106 self.ext_map = {}
107
108 def finalize_options(self):
109 _build_ext.finalize_options(self)
110 self.extensions = self.extensions or []
111 self.check_extensions_list(self.extensions)
112 self.shlibs = [ext for ext in self.extensions
113 if isinstance(ext, Library)]
114 if self.shlibs:
115 self.setup_shlib_compiler()
116 for ext in self.extensions:
117 ext._full_name = self.get_ext_fullname(ext.name)
118 for ext in self.extensions:
119 fullname = ext._full_name
120 self.ext_map[fullname] = ext
121
122 # distutils 3.1 will also ask for module names
123 # XXX what to do with conflicts?
124 self.ext_map[fullname.split('.')[-1]] = ext
125
126 ltd = ext._links_to_dynamic = \
127 self.shlibs and self.links_to_dynamic(ext) or False
128 ext._needs_stub = ltd and use_stubs and not isinstance(ext,
129 Library)
130 filename = ext._file_name = self.get_ext_filename(fullname)
131 libdir = os.path.dirname(os.path.join(self.build_lib, filename))
132 if ltd and libdir not in ext.library_dirs:
133 ext.library_dirs.append(libdir)
134 if ltd and use_stubs and os.curdir not in ext.runtime_library_dirs:
135 ext.runtime_library_dirs.append(os.curdir)
136
137 def setup_shlib_compiler(self):
138 compiler = self.shlib_compiler = new_compiler(
139 compiler=self.compiler, dry_run=self.dry_run, force=self.force
140 )
141 if sys.platform == "darwin":
142 tmp = _CONFIG_VARS.copy()
143 try:
144 # XXX Help! I don't have any idea whether these are right...
145 _CONFIG_VARS['LDSHARED'] = (
146 "gcc -Wl,-x -dynamiclib -undefined dynamic_lookup")
147 _CONFIG_VARS['CCSHARED'] = " -dynamiclib"
148 _CONFIG_VARS['SO'] = ".dylib"
149 customize_compiler(compiler)
150 finally:
151 _CONFIG_VARS.clear()
152 _CONFIG_VARS.update(tmp)
153 else:
154 customize_compiler(compiler)
155
156 if self.include_dirs is not None:
157 compiler.set_include_dirs(self.include_dirs)
158 if self.define is not None:
159 # 'define' option is a list of (name,value) tuples
160 for (name, value) in self.define:
161 compiler.define_macro(name, value)
162 if self.undef is not None:
163 for macro in self.undef:
164 compiler.undefine_macro(macro)
165 if self.libraries is not None:
166 compiler.set_libraries(self.libraries)
167 if self.library_dirs is not None:
168 compiler.set_library_dirs(self.library_dirs)
169 if self.rpath is not None:
170 compiler.set_runtime_library_dirs(self.rpath)
171 if self.link_objects is not None:
172 compiler.set_link_objects(self.link_objects)
173
174 # hack so distutils' build_extension() builds a library instead
175 compiler.link_shared_object = link_shared_object.__get__(compiler)
176
177 def get_export_symbols(self, ext):
178 if isinstance(ext, Library):
179 return ext.export_symbols
180 return _build_ext.get_export_symbols(self, ext)
181
182 def build_extension(self, ext):
183 _compiler = self.compiler
184 try:
185 if isinstance(ext, Library):
186 self.compiler = self.shlib_compiler
187 _build_ext.build_extension(self, ext)
188 if ext._needs_stub:
189 self.write_stub(
190 self.get_finalized_command('build_py').build_lib, ext
191 )
192 finally:
193 self.compiler = _compiler
194
195 def links_to_dynamic(self, ext):
196 """Return true if 'ext' links to a dynamic lib in the same package"""
197 # XXX this should check to ensure the lib is actually being built
198 # XXX as dynamic, and not just using a locally-found version or a
199 # XXX static-compiled version
200 libnames = dict.fromkeys([lib._full_name for lib in self.shlibs])
201 pkg = '.'.join(ext._full_name.split('.')[:-1] + [''])
202 for libname in ext.libraries:
203 if pkg + libname in libnames:
204 return True
205 return False
206
207 def get_outputs(self):
208 outputs = _build_ext.get_outputs(self)
209 optimize = self.get_finalized_command('build_py').optimize
210 for ext in self.extensions:
211 if ext._needs_stub:
212 base = os.path.join(self.build_lib, *ext._full_name.split('.'))
213 outputs.append(base + '.py')
214 outputs.append(base + '.pyc')
215 if optimize:
216 outputs.append(base + '.pyo')
217 return outputs
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 )
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698