"Fossies" - the Fresh Open Source Software Archive

Member "numpy-1.16.4/numpy/distutils/command/config.py" (27 May 2019, 19094 Bytes) of package /linux/misc/numpy-1.16.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "config.py" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.15.4_vs_1.16.0.

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