annotate DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/distutils/command/config.py @ 133:4acb5d8d80b6 tip

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