Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/distutils/command/config.py @ 87:2a2c65a20a8b
Add Python libs and headers
author | Chris Cannam |
---|---|
date | Wed, 25 Feb 2015 14:05:22 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
86:413a9d26189e | 87:2a2c65a20a8b |
---|---|
1 # Added Fortran compiler support to config. Currently useful only for | |
2 # try_compile call. try_run works but is untested for most of Fortran | |
3 # compilers (they must define linker_exe first). | |
4 # Pearu Peterson | |
5 from __future__ import division, absolute_import, print_function | |
6 | |
7 import os, signal | |
8 import warnings | |
9 import sys | |
10 | |
11 from distutils.command.config import config as old_config | |
12 from distutils.command.config import LANG_EXT | |
13 from distutils import log | |
14 from distutils.file_util import copy_file | |
15 from distutils.ccompiler import CompileError, LinkError | |
16 import distutils | |
17 from numpy.distutils.exec_command import exec_command | |
18 from numpy.distutils.mingw32ccompiler import generate_manifest | |
19 from numpy.distutils.command.autodist import check_inline, check_compiler_gcc4 | |
20 from numpy.distutils.compat import get_exception | |
21 | |
22 LANG_EXT['f77'] = '.f' | |
23 LANG_EXT['f90'] = '.f90' | |
24 | |
25 class config(old_config): | |
26 old_config.user_options += [ | |
27 ('fcompiler=', None, "specify the Fortran compiler type"), | |
28 ] | |
29 | |
30 def initialize_options(self): | |
31 self.fcompiler = None | |
32 old_config.initialize_options(self) | |
33 | |
34 def try_run(self, body, headers=None, include_dirs=None, | |
35 libraries=None, library_dirs=None, lang="c"): | |
36 warnings.warn("\n+++++++++++++++++++++++++++++++++++++++++++++++++\n" \ | |
37 "Usage of try_run is deprecated: please do not \n" \ | |
38 "use it anymore, and avoid configuration checks \n" \ | |
39 "involving running executable on the target machine.\n" \ | |
40 "+++++++++++++++++++++++++++++++++++++++++++++++++\n", | |
41 DeprecationWarning) | |
42 return old_config.try_run(self, body, headers, include_dirs, libraries, | |
43 library_dirs, lang) | |
44 | |
45 def _check_compiler (self): | |
46 old_config._check_compiler(self) | |
47 from numpy.distutils.fcompiler import FCompiler, new_fcompiler | |
48 | |
49 if sys.platform == 'win32' and self.compiler.compiler_type == 'msvc': | |
50 # XXX: hack to circumvent a python 2.6 bug with msvc9compiler: | |
51 # initialize call query_vcvarsall, which throws an IOError, and | |
52 # causes an error along the way without much information. We try to | |
53 # catch it here, hoping it is early enough, and print an helpful | |
54 # message instead of Error: None. | |
55 if not self.compiler.initialized: | |
56 try: | |
57 self.compiler.initialize() | |
58 except IOError: | |
59 e = get_exception() | |
60 msg = """\ | |
61 Could not initialize compiler instance: do you have Visual Studio | |
62 installed? If you are trying to build with MinGW, please use "python setup.py | |
63 build -c mingw32" instead. If you have Visual Studio installed, check it is | |
64 correctly installed, and the right version (VS 2008 for python 2.6, 2.7 and 3.2, | |
65 VS 2010 for >= 3.3). | |
66 | |
67 Original exception was: %s, and the Compiler class was %s | |
68 ============================================================================""" \ | |
69 % (e, self.compiler.__class__.__name__) | |
70 print ("""\ | |
71 ============================================================================""") | |
72 raise distutils.errors.DistutilsPlatformError(msg) | |
73 | |
74 # After MSVC is initialized, add an explicit /MANIFEST to linker | |
75 # flags. See issues gh-4245 and gh-4101 for details. Also | |
76 # relevant are issues 4431 and 16296 on the Python bug tracker. | |
77 from distutils import msvc9compiler | |
78 if msvc9compiler.get_build_version() >= 10: | |
79 for ldflags in [self.compiler.ldflags_shared, | |
80 self.compiler.ldflags_shared_debug]: | |
81 if '/MANIFEST' not in ldflags: | |
82 ldflags.append('/MANIFEST') | |
83 | |
84 if not isinstance(self.fcompiler, FCompiler): | |
85 self.fcompiler = new_fcompiler(compiler=self.fcompiler, | |
86 dry_run=self.dry_run, force=1, | |
87 c_compiler=self.compiler) | |
88 if self.fcompiler is not None: | |
89 self.fcompiler.customize(self.distribution) | |
90 if self.fcompiler.get_version(): | |
91 self.fcompiler.customize_cmd(self) | |
92 self.fcompiler.show_customization() | |
93 | |
94 def _wrap_method(self, mth, lang, args): | |
95 from distutils.ccompiler import CompileError | |
96 from distutils.errors import DistutilsExecError | |
97 save_compiler = self.compiler | |
98 if lang in ['f77', 'f90']: | |
99 self.compiler = self.fcompiler | |
100 try: | |
101 ret = mth(*((self,)+args)) | |
102 except (DistutilsExecError, CompileError): | |
103 msg = str(get_exception()) | |
104 self.compiler = save_compiler | |
105 raise CompileError | |
106 self.compiler = save_compiler | |
107 return ret | |
108 | |
109 def _compile (self, body, headers, include_dirs, lang): | |
110 return self._wrap_method(old_config._compile, lang, | |
111 (body, headers, include_dirs, lang)) | |
112 | |
113 def _link (self, body, | |
114 headers, include_dirs, | |
115 libraries, library_dirs, lang): | |
116 if self.compiler.compiler_type=='msvc': | |
117 libraries = (libraries or [])[:] | |
118 library_dirs = (library_dirs or [])[:] | |
119 if lang in ['f77', 'f90']: | |
120 lang = 'c' # always use system linker when using MSVC compiler | |
121 if self.fcompiler: | |
122 for d in self.fcompiler.library_dirs or []: | |
123 # correct path when compiling in Cygwin but with | |
124 # normal Win Python | |
125 if d.startswith('/usr/lib'): | |
126 s, o = exec_command(['cygpath', '-w', d], | |
127 use_tee=False) | |
128 if not s: d = o | |
129 library_dirs.append(d) | |
130 for libname in self.fcompiler.libraries or []: | |
131 if libname not in libraries: | |
132 libraries.append(libname) | |
133 for libname in libraries: | |
134 if libname.startswith('msvc'): continue | |
135 fileexists = False | |
136 for libdir in library_dirs or []: | |
137 libfile = os.path.join(libdir, '%s.lib' % (libname)) | |
138 if os.path.isfile(libfile): | |
139 fileexists = True | |
140 break | |
141 if fileexists: continue | |
142 # make g77-compiled static libs available to MSVC | |
143 fileexists = False | |
144 for libdir in library_dirs: | |
145 libfile = os.path.join(libdir, 'lib%s.a' % (libname)) | |
146 if os.path.isfile(libfile): | |
147 # copy libname.a file to name.lib so that MSVC linker | |
148 # can find it | |
149 libfile2 = os.path.join(libdir, '%s.lib' % (libname)) | |
150 copy_file(libfile, libfile2) | |
151 self.temp_files.append(libfile2) | |
152 fileexists = True | |
153 break | |
154 if fileexists: continue | |
155 log.warn('could not find library %r in directories %s' \ | |
156 % (libname, library_dirs)) | |
157 elif self.compiler.compiler_type == 'mingw32': | |
158 generate_manifest(self) | |
159 return self._wrap_method(old_config._link, lang, | |
160 (body, headers, include_dirs, | |
161 libraries, library_dirs, lang)) | |
162 | |
163 def check_header(self, header, include_dirs=None, library_dirs=None, lang='c'): | |
164 self._check_compiler() | |
165 return self.try_compile( | |
166 "/* we need a dummy line to make distutils happy */", | |
167 [header], include_dirs) | |
168 | |
169 def check_decl(self, symbol, | |
170 headers=None, include_dirs=None): | |
171 self._check_compiler() | |
172 body = """ | |
173 int main() | |
174 { | |
175 #ifndef %s | |
176 (void) %s; | |
177 #endif | |
178 ; | |
179 return 0; | |
180 }""" % (symbol, symbol) | |
181 | |
182 return self.try_compile(body, headers, include_dirs) | |
183 | |
184 def check_macro_true(self, symbol, | |
185 headers=None, include_dirs=None): | |
186 self._check_compiler() | |
187 body = """ | |
188 int main() | |
189 { | |
190 #if %s | |
191 #else | |
192 #error false or undefined macro | |
193 #endif | |
194 ; | |
195 return 0; | |
196 }""" % (symbol,) | |
197 | |
198 return self.try_compile(body, headers, include_dirs) | |
199 | |
200 def check_type(self, type_name, headers=None, include_dirs=None, | |
201 library_dirs=None): | |
202 """Check type availability. Return True if the type can be compiled, | |
203 False otherwise""" | |
204 self._check_compiler() | |
205 | |
206 # First check the type can be compiled | |
207 body = r""" | |
208 int main() { | |
209 if ((%(name)s *) 0) | |
210 return 0; | |
211 if (sizeof (%(name)s)) | |
212 return 0; | |
213 } | |
214 """ % {'name': type_name} | |
215 | |
216 st = False | |
217 try: | |
218 try: | |
219 self._compile(body % {'type': type_name}, | |
220 headers, include_dirs, 'c') | |
221 st = True | |
222 except distutils.errors.CompileError: | |
223 st = False | |
224 finally: | |
225 self._clean() | |
226 | |
227 return st | |
228 | |
229 def check_type_size(self, type_name, headers=None, include_dirs=None, library_dirs=None, expected=None): | |
230 """Check size of a given type.""" | |
231 self._check_compiler() | |
232 | |
233 # First check the type can be compiled | |
234 body = r""" | |
235 typedef %(type)s npy_check_sizeof_type; | |
236 int main () | |
237 { | |
238 static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) >= 0)]; | |
239 test_array [0] = 0 | |
240 | |
241 ; | |
242 return 0; | |
243 } | |
244 """ | |
245 self._compile(body % {'type': type_name}, | |
246 headers, include_dirs, 'c') | |
247 self._clean() | |
248 | |
249 if expected: | |
250 body = r""" | |
251 typedef %(type)s npy_check_sizeof_type; | |
252 int main () | |
253 { | |
254 static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) == %(size)s)]; | |
255 test_array [0] = 0 | |
256 | |
257 ; | |
258 return 0; | |
259 } | |
260 """ | |
261 for size in expected: | |
262 try: | |
263 self._compile(body % {'type': type_name, 'size': size}, | |
264 headers, include_dirs, 'c') | |
265 self._clean() | |
266 return size | |
267 except CompileError: | |
268 pass | |
269 | |
270 # this fails to *compile* if size > sizeof(type) | |
271 body = r""" | |
272 typedef %(type)s npy_check_sizeof_type; | |
273 int main () | |
274 { | |
275 static int test_array [1 - 2 * !(((long) (sizeof (npy_check_sizeof_type))) <= %(size)s)]; | |
276 test_array [0] = 0 | |
277 | |
278 ; | |
279 return 0; | |
280 } | |
281 """ | |
282 | |
283 # The principle is simple: we first find low and high bounds of size | |
284 # for the type, where low/high are looked up on a log scale. Then, we | |
285 # do a binary search to find the exact size between low and high | |
286 low = 0 | |
287 mid = 0 | |
288 while True: | |
289 try: | |
290 self._compile(body % {'type': type_name, 'size': mid}, | |
291 headers, include_dirs, 'c') | |
292 self._clean() | |
293 break | |
294 except CompileError: | |
295 #log.info("failure to test for bound %d" % mid) | |
296 low = mid + 1 | |
297 mid = 2 * mid + 1 | |
298 | |
299 high = mid | |
300 # Binary search: | |
301 while low != high: | |
302 mid = (high - low) // 2 + low | |
303 try: | |
304 self._compile(body % {'type': type_name, 'size': mid}, | |
305 headers, include_dirs, 'c') | |
306 self._clean() | |
307 high = mid | |
308 except CompileError: | |
309 low = mid + 1 | |
310 return low | |
311 | |
312 def check_func(self, func, | |
313 headers=None, include_dirs=None, | |
314 libraries=None, library_dirs=None, | |
315 decl=False, call=False, call_args=None): | |
316 # clean up distutils's config a bit: add void to main(), and | |
317 # return a value. | |
318 self._check_compiler() | |
319 body = [] | |
320 if decl: | |
321 if type(decl) == str: | |
322 body.append(decl) | |
323 else: | |
324 body.append("int %s (void);" % func) | |
325 # Handle MSVC intrinsics: force MS compiler to make a function call. | |
326 # Useful to test for some functions when built with optimization on, to | |
327 # avoid build error because the intrinsic and our 'fake' test | |
328 # declaration do not match. | |
329 body.append("#ifdef _MSC_VER") | |
330 body.append("#pragma function(%s)" % func) | |
331 body.append("#endif") | |
332 body.append("int main (void) {") | |
333 if call: | |
334 if call_args is None: | |
335 call_args = '' | |
336 body.append(" %s(%s);" % (func, call_args)) | |
337 else: | |
338 body.append(" %s;" % func) | |
339 body.append(" return 0;") | |
340 body.append("}") | |
341 body = '\n'.join(body) + "\n" | |
342 | |
343 return self.try_link(body, headers, include_dirs, | |
344 libraries, library_dirs) | |
345 | |
346 def check_funcs_once(self, funcs, | |
347 headers=None, include_dirs=None, | |
348 libraries=None, library_dirs=None, | |
349 decl=False, call=False, call_args=None): | |
350 """Check a list of functions at once. | |
351 | |
352 This is useful to speed up things, since all the functions in the funcs | |
353 list will be put in one compilation unit. | |
354 | |
355 Arguments | |
356 --------- | |
357 funcs : seq | |
358 list of functions to test | |
359 include_dirs : seq | |
360 list of header paths | |
361 libraries : seq | |
362 list of libraries to link the code snippet to | |
363 libraru_dirs : seq | |
364 list of library paths | |
365 decl : dict | |
366 for every (key, value), the declaration in the value will be | |
367 used for function in key. If a function is not in the | |
368 dictionay, no declaration will be used. | |
369 call : dict | |
370 for every item (f, value), if the value is True, a call will be | |
371 done to the function f. | |
372 """ | |
373 self._check_compiler() | |
374 body = [] | |
375 if decl: | |
376 for f, v in decl.items(): | |
377 if v: | |
378 body.append("int %s (void);" % f) | |
379 | |
380 # Handle MS intrinsics. See check_func for more info. | |
381 body.append("#ifdef _MSC_VER") | |
382 for func in funcs: | |
383 body.append("#pragma function(%s)" % func) | |
384 body.append("#endif") | |
385 | |
386 body.append("int main (void) {") | |
387 if call: | |
388 for f in funcs: | |
389 if f in call and call[f]: | |
390 if not (call_args and f in call_args and call_args[f]): | |
391 args = '' | |
392 else: | |
393 args = call_args[f] | |
394 body.append(" %s(%s);" % (f, args)) | |
395 else: | |
396 body.append(" %s;" % f) | |
397 else: | |
398 for f in funcs: | |
399 body.append(" %s;" % f) | |
400 body.append(" return 0;") | |
401 body.append("}") | |
402 body = '\n'.join(body) + "\n" | |
403 | |
404 return self.try_link(body, headers, include_dirs, | |
405 libraries, library_dirs) | |
406 | |
407 def check_inline(self): | |
408 """Return the inline keyword recognized by the compiler, empty string | |
409 otherwise.""" | |
410 return check_inline(self) | |
411 | |
412 def check_compiler_gcc4(self): | |
413 """Return True if the C compiler is gcc >= 4.""" | |
414 return check_compiler_gcc4(self) | |
415 | |
416 def get_output(self, body, headers=None, include_dirs=None, | |
417 libraries=None, library_dirs=None, | |
418 lang="c", use_tee=None): | |
419 """Try to compile, link to an executable, and run a program | |
420 built from 'body' and 'headers'. Returns the exit status code | |
421 of the program and its output. | |
422 """ | |
423 warnings.warn("\n+++++++++++++++++++++++++++++++++++++++++++++++++\n" \ | |
424 "Usage of get_output is deprecated: please do not \n" \ | |
425 "use it anymore, and avoid configuration checks \n" \ | |
426 "involving running executable on the target machine.\n" \ | |
427 "+++++++++++++++++++++++++++++++++++++++++++++++++\n", | |
428 DeprecationWarning) | |
429 from distutils.ccompiler import CompileError, LinkError | |
430 self._check_compiler() | |
431 exitcode, output = 255, '' | |
432 try: | |
433 grabber = GrabStdout() | |
434 try: | |
435 src, obj, exe = self._link(body, headers, include_dirs, | |
436 libraries, library_dirs, lang) | |
437 grabber.restore() | |
438 except: | |
439 output = grabber.data | |
440 grabber.restore() | |
441 raise | |
442 exe = os.path.join('.', exe) | |
443 exitstatus, output = exec_command(exe, execute_in='.', | |
444 use_tee=use_tee) | |
445 if hasattr(os, 'WEXITSTATUS'): | |
446 exitcode = os.WEXITSTATUS(exitstatus) | |
447 if os.WIFSIGNALED(exitstatus): | |
448 sig = os.WTERMSIG(exitstatus) | |
449 log.error('subprocess exited with signal %d' % (sig,)) | |
450 if sig == signal.SIGINT: | |
451 # control-C | |
452 raise KeyboardInterrupt | |
453 else: | |
454 exitcode = exitstatus | |
455 log.info("success!") | |
456 except (CompileError, LinkError): | |
457 log.info("failure.") | |
458 self._clean() | |
459 return exitcode, output | |
460 | |
461 class GrabStdout(object): | |
462 | |
463 def __init__(self): | |
464 self.sys_stdout = sys.stdout | |
465 self.data = '' | |
466 sys.stdout = self | |
467 | |
468 def write (self, data): | |
469 self.sys_stdout.write(data) | |
470 self.data += data | |
471 | |
472 def flush (self): | |
473 self.sys_stdout.flush() | |
474 | |
475 def restore(self): | |
476 sys.stdout = self.sys_stdout |