annotate DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/distutils/system_info.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 #!/bin/env python
Chris@87 2 """
Chris@87 3 This file defines a set of system_info classes for getting
Chris@87 4 information about various resources (libraries, library directories,
Chris@87 5 include directories, etc.) in the system. Currently, the following
Chris@87 6 classes are available:
Chris@87 7
Chris@87 8 atlas_info
Chris@87 9 atlas_threads_info
Chris@87 10 atlas_blas_info
Chris@87 11 atlas_blas_threads_info
Chris@87 12 lapack_atlas_info
Chris@87 13 blas_info
Chris@87 14 lapack_info
Chris@87 15 openblas_info
Chris@87 16 blas_opt_info # usage recommended
Chris@87 17 lapack_opt_info # usage recommended
Chris@87 18 fftw_info,dfftw_info,sfftw_info
Chris@87 19 fftw_threads_info,dfftw_threads_info,sfftw_threads_info
Chris@87 20 djbfft_info
Chris@87 21 x11_info
Chris@87 22 lapack_src_info
Chris@87 23 blas_src_info
Chris@87 24 numpy_info
Chris@87 25 numarray_info
Chris@87 26 numpy_info
Chris@87 27 boost_python_info
Chris@87 28 agg2_info
Chris@87 29 wx_info
Chris@87 30 gdk_pixbuf_xlib_2_info
Chris@87 31 gdk_pixbuf_2_info
Chris@87 32 gdk_x11_2_info
Chris@87 33 gtkp_x11_2_info
Chris@87 34 gtkp_2_info
Chris@87 35 xft_info
Chris@87 36 freetype2_info
Chris@87 37 umfpack_info
Chris@87 38
Chris@87 39 Usage:
Chris@87 40 info_dict = get_info(<name>)
Chris@87 41 where <name> is a string 'atlas','x11','fftw','lapack','blas',
Chris@87 42 'lapack_src', 'blas_src', etc. For a complete list of allowed names,
Chris@87 43 see the definition of get_info() function below.
Chris@87 44
Chris@87 45 Returned info_dict is a dictionary which is compatible with
Chris@87 46 distutils.setup keyword arguments. If info_dict == {}, then the
Chris@87 47 asked resource is not available (system_info could not find it).
Chris@87 48
Chris@87 49 Several *_info classes specify an environment variable to specify
Chris@87 50 the locations of software. When setting the corresponding environment
Chris@87 51 variable to 'None' then the software will be ignored, even when it
Chris@87 52 is available in system.
Chris@87 53
Chris@87 54 Global parameters:
Chris@87 55 system_info.search_static_first - search static libraries (.a)
Chris@87 56 in precedence to shared ones (.so, .sl) if enabled.
Chris@87 57 system_info.verbosity - output the results to stdout if enabled.
Chris@87 58
Chris@87 59 The file 'site.cfg' is looked for in
Chris@87 60
Chris@87 61 1) Directory of main setup.py file being run.
Chris@87 62 2) Home directory of user running the setup.py file as ~/.numpy-site.cfg
Chris@87 63 3) System wide directory (location of this file...)
Chris@87 64
Chris@87 65 The first one found is used to get system configuration options The
Chris@87 66 format is that used by ConfigParser (i.e., Windows .INI style). The
Chris@87 67 section ALL has options that are the default for each section. The
Chris@87 68 available sections are fftw, atlas, and x11. Appropiate defaults are
Chris@87 69 used if nothing is specified.
Chris@87 70
Chris@87 71 The order of finding the locations of resources is the following:
Chris@87 72 1. environment variable
Chris@87 73 2. section in site.cfg
Chris@87 74 3. ALL section in site.cfg
Chris@87 75 Only the first complete match is returned.
Chris@87 76
Chris@87 77 Example:
Chris@87 78 ----------
Chris@87 79 [ALL]
Chris@87 80 library_dirs = /usr/lib:/usr/local/lib:/opt/lib
Chris@87 81 include_dirs = /usr/include:/usr/local/include:/opt/include
Chris@87 82 src_dirs = /usr/local/src:/opt/src
Chris@87 83 # search static libraries (.a) in preference to shared ones (.so)
Chris@87 84 search_static_first = 0
Chris@87 85
Chris@87 86 [fftw]
Chris@87 87 fftw_libs = rfftw, fftw
Chris@87 88 fftw_opt_libs = rfftw_threaded, fftw_threaded
Chris@87 89 # if the above aren't found, look for {s,d}fftw_libs and {s,d}fftw_opt_libs
Chris@87 90
Chris@87 91 [atlas]
Chris@87 92 library_dirs = /usr/lib/3dnow:/usr/lib/3dnow/atlas
Chris@87 93 # for overriding the names of the atlas libraries
Chris@87 94 atlas_libs = lapack, f77blas, cblas, atlas
Chris@87 95
Chris@87 96 [x11]
Chris@87 97 library_dirs = /usr/X11R6/lib
Chris@87 98 include_dirs = /usr/X11R6/include
Chris@87 99 ----------
Chris@87 100
Chris@87 101 Authors:
Chris@87 102 Pearu Peterson <pearu@cens.ioc.ee>, February 2002
Chris@87 103 David M. Cooke <cookedm@physics.mcmaster.ca>, April 2002
Chris@87 104
Chris@87 105 Copyright 2002 Pearu Peterson all rights reserved,
Chris@87 106 Pearu Peterson <pearu@cens.ioc.ee>
Chris@87 107 Permission to use, modify, and distribute this software is given under the
Chris@87 108 terms of the NumPy (BSD style) license. See LICENSE.txt that came with
Chris@87 109 this distribution for specifics.
Chris@87 110
Chris@87 111 NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
Chris@87 112
Chris@87 113 """
Chris@87 114 from __future__ import division, absolute_import, print_function
Chris@87 115
Chris@87 116 import sys
Chris@87 117 import os
Chris@87 118 import re
Chris@87 119 import copy
Chris@87 120 import warnings
Chris@87 121 from glob import glob
Chris@87 122 from functools import reduce
Chris@87 123 if sys.version_info[0] < 3:
Chris@87 124 from ConfigParser import NoOptionError, ConfigParser
Chris@87 125 else:
Chris@87 126 from configparser import NoOptionError, ConfigParser
Chris@87 127
Chris@87 128 from distutils.errors import DistutilsError
Chris@87 129 from distutils.dist import Distribution
Chris@87 130 import distutils.sysconfig
Chris@87 131 from distutils import log
Chris@87 132 from distutils.util import get_platform
Chris@87 133
Chris@87 134 from numpy.distutils.exec_command import \
Chris@87 135 find_executable, exec_command, get_pythonexe
Chris@87 136 from numpy.distutils.misc_util import is_sequence, is_string, \
Chris@87 137 get_shared_lib_extension
Chris@87 138 from numpy.distutils.command.config import config as cmd_config
Chris@87 139 from numpy.distutils.compat import get_exception
Chris@87 140 import distutils.ccompiler
Chris@87 141 import tempfile
Chris@87 142 import shutil
Chris@87 143
Chris@87 144
Chris@87 145 # Determine number of bits
Chris@87 146 import platform
Chris@87 147 _bits = {'32bit': 32, '64bit': 64}
Chris@87 148 platform_bits = _bits[platform.architecture()[0]]
Chris@87 149
Chris@87 150
Chris@87 151 def libpaths(paths, bits):
Chris@87 152 """Return a list of library paths valid on 32 or 64 bit systems.
Chris@87 153
Chris@87 154 Inputs:
Chris@87 155 paths : sequence
Chris@87 156 A sequence of strings (typically paths)
Chris@87 157 bits : int
Chris@87 158 An integer, the only valid values are 32 or 64. A ValueError exception
Chris@87 159 is raised otherwise.
Chris@87 160
Chris@87 161 Examples:
Chris@87 162
Chris@87 163 Consider a list of directories
Chris@87 164 >>> paths = ['/usr/X11R6/lib','/usr/X11/lib','/usr/lib']
Chris@87 165
Chris@87 166 For a 32-bit platform, this is already valid:
Chris@87 167 >>> np.distutils.system_info.libpaths(paths,32)
Chris@87 168 ['/usr/X11R6/lib', '/usr/X11/lib', '/usr/lib']
Chris@87 169
Chris@87 170 On 64 bits, we prepend the '64' postfix
Chris@87 171 >>> np.distutils.system_info.libpaths(paths,64)
Chris@87 172 ['/usr/X11R6/lib64', '/usr/X11R6/lib', '/usr/X11/lib64', '/usr/X11/lib',
Chris@87 173 '/usr/lib64', '/usr/lib']
Chris@87 174 """
Chris@87 175 if bits not in (32, 64):
Chris@87 176 raise ValueError("Invalid bit size in libpaths: 32 or 64 only")
Chris@87 177
Chris@87 178 # Handle 32bit case
Chris@87 179 if bits == 32:
Chris@87 180 return paths
Chris@87 181
Chris@87 182 # Handle 64bit case
Chris@87 183 out = []
Chris@87 184 for p in paths:
Chris@87 185 out.extend([p + '64', p])
Chris@87 186
Chris@87 187 return out
Chris@87 188
Chris@87 189
Chris@87 190 if sys.platform == 'win32':
Chris@87 191 default_lib_dirs = ['C:\\',
Chris@87 192 os.path.join(distutils.sysconfig.EXEC_PREFIX,
Chris@87 193 'libs')]
Chris@87 194 default_include_dirs = []
Chris@87 195 default_src_dirs = ['.']
Chris@87 196 default_x11_lib_dirs = []
Chris@87 197 default_x11_include_dirs = []
Chris@87 198 else:
Chris@87 199 default_lib_dirs = libpaths(['/usr/local/lib', '/opt/lib', '/usr/lib',
Chris@87 200 '/opt/local/lib', '/sw/lib'], platform_bits)
Chris@87 201 default_include_dirs = ['/usr/local/include',
Chris@87 202 '/opt/include', '/usr/include',
Chris@87 203 # path of umfpack under macports
Chris@87 204 '/opt/local/include/ufsparse',
Chris@87 205 '/opt/local/include', '/sw/include',
Chris@87 206 '/usr/include/suitesparse']
Chris@87 207 default_src_dirs = ['.', '/usr/local/src', '/opt/src', '/sw/src']
Chris@87 208
Chris@87 209 default_x11_lib_dirs = libpaths(['/usr/X11R6/lib', '/usr/X11/lib',
Chris@87 210 '/usr/lib'], platform_bits)
Chris@87 211 default_x11_include_dirs = ['/usr/X11R6/include', '/usr/X11/include',
Chris@87 212 '/usr/include']
Chris@87 213
Chris@87 214 if os.path.exists('/usr/lib/X11'):
Chris@87 215 globbed_x11_dir = glob('/usr/lib/*/libX11.so')
Chris@87 216 if globbed_x11_dir:
Chris@87 217 x11_so_dir = os.path.split(globbed_x11_dir[0])[0]
Chris@87 218 default_x11_lib_dirs.extend([x11_so_dir, '/usr/lib/X11'])
Chris@87 219 default_x11_include_dirs.extend(['/usr/lib/X11/include',
Chris@87 220 '/usr/include/X11'])
Chris@87 221
Chris@87 222 import subprocess as sp
Chris@87 223 tmp = None
Chris@87 224 try:
Chris@87 225 # Explicitly open/close file to avoid ResourceWarning when
Chris@87 226 # tests are run in debug mode Python 3.
Chris@87 227 tmp = open(os.devnull, 'w')
Chris@87 228 p = sp.Popen(["gcc", "-print-multiarch"], stdout=sp.PIPE,
Chris@87 229 stderr=tmp)
Chris@87 230 except (OSError, DistutilsError):
Chris@87 231 # OSError if gcc is not installed, or SandboxViolation (DistutilsError
Chris@87 232 # subclass) if an old setuptools bug is triggered (see gh-3160).
Chris@87 233 pass
Chris@87 234 else:
Chris@87 235 triplet = str(p.communicate()[0].decode().strip())
Chris@87 236 if p.returncode == 0:
Chris@87 237 # gcc supports the "-print-multiarch" option
Chris@87 238 default_x11_lib_dirs += [os.path.join("/usr/lib/", triplet)]
Chris@87 239 default_lib_dirs += [os.path.join("/usr/lib/", triplet)]
Chris@87 240 finally:
Chris@87 241 if tmp is not None:
Chris@87 242 tmp.close()
Chris@87 243
Chris@87 244 if os.path.join(sys.prefix, 'lib') not in default_lib_dirs:
Chris@87 245 default_lib_dirs.insert(0, os.path.join(sys.prefix, 'lib'))
Chris@87 246 default_include_dirs.append(os.path.join(sys.prefix, 'include'))
Chris@87 247 default_src_dirs.append(os.path.join(sys.prefix, 'src'))
Chris@87 248
Chris@87 249 default_lib_dirs = [_m for _m in default_lib_dirs if os.path.isdir(_m)]
Chris@87 250 default_include_dirs = [_m for _m in default_include_dirs if os.path.isdir(_m)]
Chris@87 251 default_src_dirs = [_m for _m in default_src_dirs if os.path.isdir(_m)]
Chris@87 252
Chris@87 253 so_ext = get_shared_lib_extension()
Chris@87 254
Chris@87 255
Chris@87 256 def get_standard_file(fname):
Chris@87 257 """Returns a list of files named 'fname' from
Chris@87 258 1) System-wide directory (directory-location of this module)
Chris@87 259 2) Users HOME directory (os.environ['HOME'])
Chris@87 260 3) Local directory
Chris@87 261 """
Chris@87 262 # System-wide file
Chris@87 263 filenames = []
Chris@87 264 try:
Chris@87 265 f = __file__
Chris@87 266 except NameError:
Chris@87 267 f = sys.argv[0]
Chris@87 268 else:
Chris@87 269 sysfile = os.path.join(os.path.split(os.path.abspath(f))[0],
Chris@87 270 fname)
Chris@87 271 if os.path.isfile(sysfile):
Chris@87 272 filenames.append(sysfile)
Chris@87 273
Chris@87 274 # Home directory
Chris@87 275 # And look for the user config file
Chris@87 276 try:
Chris@87 277 f = os.path.expanduser('~')
Chris@87 278 except KeyError:
Chris@87 279 pass
Chris@87 280 else:
Chris@87 281 user_file = os.path.join(f, fname)
Chris@87 282 if os.path.isfile(user_file):
Chris@87 283 filenames.append(user_file)
Chris@87 284
Chris@87 285 # Local file
Chris@87 286 if os.path.isfile(fname):
Chris@87 287 filenames.append(os.path.abspath(fname))
Chris@87 288
Chris@87 289 return filenames
Chris@87 290
Chris@87 291
Chris@87 292 def get_info(name, notfound_action=0):
Chris@87 293 """
Chris@87 294 notfound_action:
Chris@87 295 0 - do nothing
Chris@87 296 1 - display warning message
Chris@87 297 2 - raise error
Chris@87 298 """
Chris@87 299 cl = {'atlas': atlas_info, # use lapack_opt or blas_opt instead
Chris@87 300 'atlas_threads': atlas_threads_info, # ditto
Chris@87 301 'atlas_blas': atlas_blas_info,
Chris@87 302 'atlas_blas_threads': atlas_blas_threads_info,
Chris@87 303 'lapack_atlas': lapack_atlas_info, # use lapack_opt instead
Chris@87 304 'lapack_atlas_threads': lapack_atlas_threads_info, # ditto
Chris@87 305 'mkl': mkl_info,
Chris@87 306 # openblas which may or may not have embedded lapack
Chris@87 307 'openblas': openblas_info, # use blas_opt instead
Chris@87 308 # openblas with embedded lapack
Chris@87 309 'openblas_lapack': openblas_lapack_info, # use blas_opt instead
Chris@87 310 'lapack_mkl': lapack_mkl_info, # use lapack_opt instead
Chris@87 311 'blas_mkl': blas_mkl_info, # use blas_opt instead
Chris@87 312 'x11': x11_info,
Chris@87 313 'fft_opt': fft_opt_info,
Chris@87 314 'fftw': fftw_info,
Chris@87 315 'fftw2': fftw2_info,
Chris@87 316 'fftw3': fftw3_info,
Chris@87 317 'dfftw': dfftw_info,
Chris@87 318 'sfftw': sfftw_info,
Chris@87 319 'fftw_threads': fftw_threads_info,
Chris@87 320 'dfftw_threads': dfftw_threads_info,
Chris@87 321 'sfftw_threads': sfftw_threads_info,
Chris@87 322 'djbfft': djbfft_info,
Chris@87 323 'blas': blas_info, # use blas_opt instead
Chris@87 324 'lapack': lapack_info, # use lapack_opt instead
Chris@87 325 'lapack_src': lapack_src_info,
Chris@87 326 'blas_src': blas_src_info,
Chris@87 327 'numpy': numpy_info,
Chris@87 328 'f2py': f2py_info,
Chris@87 329 'Numeric': Numeric_info,
Chris@87 330 'numeric': Numeric_info,
Chris@87 331 'numarray': numarray_info,
Chris@87 332 'numerix': numerix_info,
Chris@87 333 'lapack_opt': lapack_opt_info,
Chris@87 334 'blas_opt': blas_opt_info,
Chris@87 335 'boost_python': boost_python_info,
Chris@87 336 'agg2': agg2_info,
Chris@87 337 'wx': wx_info,
Chris@87 338 'gdk_pixbuf_xlib_2': gdk_pixbuf_xlib_2_info,
Chris@87 339 'gdk-pixbuf-xlib-2.0': gdk_pixbuf_xlib_2_info,
Chris@87 340 'gdk_pixbuf_2': gdk_pixbuf_2_info,
Chris@87 341 'gdk-pixbuf-2.0': gdk_pixbuf_2_info,
Chris@87 342 'gdk': gdk_info,
Chris@87 343 'gdk_2': gdk_2_info,
Chris@87 344 'gdk-2.0': gdk_2_info,
Chris@87 345 'gdk_x11_2': gdk_x11_2_info,
Chris@87 346 'gdk-x11-2.0': gdk_x11_2_info,
Chris@87 347 'gtkp_x11_2': gtkp_x11_2_info,
Chris@87 348 'gtk+-x11-2.0': gtkp_x11_2_info,
Chris@87 349 'gtkp_2': gtkp_2_info,
Chris@87 350 'gtk+-2.0': gtkp_2_info,
Chris@87 351 'xft': xft_info,
Chris@87 352 'freetype2': freetype2_info,
Chris@87 353 'umfpack': umfpack_info,
Chris@87 354 'amd': amd_info,
Chris@87 355 }.get(name.lower(), system_info)
Chris@87 356 return cl().get_info(notfound_action)
Chris@87 357
Chris@87 358
Chris@87 359 class NotFoundError(DistutilsError):
Chris@87 360 """Some third-party program or library is not found."""
Chris@87 361
Chris@87 362
Chris@87 363 class AtlasNotFoundError(NotFoundError):
Chris@87 364 """
Chris@87 365 Atlas (http://math-atlas.sourceforge.net/) libraries not found.
Chris@87 366 Directories to search for the libraries can be specified in the
Chris@87 367 numpy/distutils/site.cfg file (section [atlas]) or by setting
Chris@87 368 the ATLAS environment variable."""
Chris@87 369
Chris@87 370
Chris@87 371 class LapackNotFoundError(NotFoundError):
Chris@87 372 """
Chris@87 373 Lapack (http://www.netlib.org/lapack/) libraries not found.
Chris@87 374 Directories to search for the libraries can be specified in the
Chris@87 375 numpy/distutils/site.cfg file (section [lapack]) or by setting
Chris@87 376 the LAPACK environment variable."""
Chris@87 377
Chris@87 378
Chris@87 379 class LapackSrcNotFoundError(LapackNotFoundError):
Chris@87 380 """
Chris@87 381 Lapack (http://www.netlib.org/lapack/) sources not found.
Chris@87 382 Directories to search for the sources can be specified in the
Chris@87 383 numpy/distutils/site.cfg file (section [lapack_src]) or by setting
Chris@87 384 the LAPACK_SRC environment variable."""
Chris@87 385
Chris@87 386
Chris@87 387 class BlasNotFoundError(NotFoundError):
Chris@87 388 """
Chris@87 389 Blas (http://www.netlib.org/blas/) libraries not found.
Chris@87 390 Directories to search for the libraries can be specified in the
Chris@87 391 numpy/distutils/site.cfg file (section [blas]) or by setting
Chris@87 392 the BLAS environment variable."""
Chris@87 393
Chris@87 394
Chris@87 395 class BlasSrcNotFoundError(BlasNotFoundError):
Chris@87 396 """
Chris@87 397 Blas (http://www.netlib.org/blas/) sources not found.
Chris@87 398 Directories to search for the sources can be specified in the
Chris@87 399 numpy/distutils/site.cfg file (section [blas_src]) or by setting
Chris@87 400 the BLAS_SRC environment variable."""
Chris@87 401
Chris@87 402
Chris@87 403 class FFTWNotFoundError(NotFoundError):
Chris@87 404 """
Chris@87 405 FFTW (http://www.fftw.org/) libraries not found.
Chris@87 406 Directories to search for the libraries can be specified in the
Chris@87 407 numpy/distutils/site.cfg file (section [fftw]) or by setting
Chris@87 408 the FFTW environment variable."""
Chris@87 409
Chris@87 410
Chris@87 411 class DJBFFTNotFoundError(NotFoundError):
Chris@87 412 """
Chris@87 413 DJBFFT (http://cr.yp.to/djbfft.html) libraries not found.
Chris@87 414 Directories to search for the libraries can be specified in the
Chris@87 415 numpy/distutils/site.cfg file (section [djbfft]) or by setting
Chris@87 416 the DJBFFT environment variable."""
Chris@87 417
Chris@87 418
Chris@87 419 class NumericNotFoundError(NotFoundError):
Chris@87 420 """
Chris@87 421 Numeric (http://www.numpy.org/) module not found.
Chris@87 422 Get it from above location, install it, and retry setup.py."""
Chris@87 423
Chris@87 424
Chris@87 425 class X11NotFoundError(NotFoundError):
Chris@87 426 """X11 libraries not found."""
Chris@87 427
Chris@87 428
Chris@87 429 class UmfpackNotFoundError(NotFoundError):
Chris@87 430 """
Chris@87 431 UMFPACK sparse solver (http://www.cise.ufl.edu/research/sparse/umfpack/)
Chris@87 432 not found. Directories to search for the libraries can be specified in the
Chris@87 433 numpy/distutils/site.cfg file (section [umfpack]) or by setting
Chris@87 434 the UMFPACK environment variable."""
Chris@87 435
Chris@87 436
Chris@87 437 class system_info:
Chris@87 438
Chris@87 439 """ get_info() is the only public method. Don't use others.
Chris@87 440 """
Chris@87 441 section = 'ALL'
Chris@87 442 dir_env_var = None
Chris@87 443 search_static_first = 0 # XXX: disabled by default, may disappear in
Chris@87 444 # future unless it is proved to be useful.
Chris@87 445 verbosity = 1
Chris@87 446 saved_results = {}
Chris@87 447
Chris@87 448 notfounderror = NotFoundError
Chris@87 449
Chris@87 450 def __init__(self,
Chris@87 451 default_lib_dirs=default_lib_dirs,
Chris@87 452 default_include_dirs=default_include_dirs,
Chris@87 453 verbosity=1,
Chris@87 454 ):
Chris@87 455 self.__class__.info = {}
Chris@87 456 self.local_prefixes = []
Chris@87 457 defaults = {}
Chris@87 458 defaults['library_dirs'] = os.pathsep.join(default_lib_dirs)
Chris@87 459 defaults['include_dirs'] = os.pathsep.join(default_include_dirs)
Chris@87 460 defaults['src_dirs'] = os.pathsep.join(default_src_dirs)
Chris@87 461 defaults['search_static_first'] = str(self.search_static_first)
Chris@87 462 self.cp = ConfigParser(defaults)
Chris@87 463 self.files = []
Chris@87 464 self.files.extend(get_standard_file('.numpy-site.cfg'))
Chris@87 465 self.files.extend(get_standard_file('site.cfg'))
Chris@87 466 self.parse_config_files()
Chris@87 467 if self.section is not None:
Chris@87 468 self.search_static_first = self.cp.getboolean(
Chris@87 469 self.section, 'search_static_first')
Chris@87 470 assert isinstance(self.search_static_first, int)
Chris@87 471
Chris@87 472 def parse_config_files(self):
Chris@87 473 self.cp.read(self.files)
Chris@87 474 if not self.cp.has_section(self.section):
Chris@87 475 if self.section is not None:
Chris@87 476 self.cp.add_section(self.section)
Chris@87 477
Chris@87 478 def calc_libraries_info(self):
Chris@87 479 libs = self.get_libraries()
Chris@87 480 dirs = self.get_lib_dirs()
Chris@87 481 info = {}
Chris@87 482 for lib in libs:
Chris@87 483 i = self.check_libs(dirs, [lib])
Chris@87 484 if i is not None:
Chris@87 485 dict_append(info, **i)
Chris@87 486 else:
Chris@87 487 log.info('Library %s was not found. Ignoring' % (lib))
Chris@87 488 return info
Chris@87 489
Chris@87 490 def set_info(self, **info):
Chris@87 491 if info:
Chris@87 492 lib_info = self.calc_libraries_info()
Chris@87 493 dict_append(info, **lib_info)
Chris@87 494 self.saved_results[self.__class__.__name__] = info
Chris@87 495
Chris@87 496 def has_info(self):
Chris@87 497 return self.__class__.__name__ in self.saved_results
Chris@87 498
Chris@87 499 def get_info(self, notfound_action=0):
Chris@87 500 """ Return a dictonary with items that are compatible
Chris@87 501 with numpy.distutils.setup keyword arguments.
Chris@87 502 """
Chris@87 503 flag = 0
Chris@87 504 if not self.has_info():
Chris@87 505 flag = 1
Chris@87 506 log.info(self.__class__.__name__ + ':')
Chris@87 507 if hasattr(self, 'calc_info'):
Chris@87 508 self.calc_info()
Chris@87 509 if notfound_action:
Chris@87 510 if not self.has_info():
Chris@87 511 if notfound_action == 1:
Chris@87 512 warnings.warn(self.notfounderror.__doc__)
Chris@87 513 elif notfound_action == 2:
Chris@87 514 raise self.notfounderror(self.notfounderror.__doc__)
Chris@87 515 else:
Chris@87 516 raise ValueError(repr(notfound_action))
Chris@87 517
Chris@87 518 if not self.has_info():
Chris@87 519 log.info(' NOT AVAILABLE')
Chris@87 520 self.set_info()
Chris@87 521 else:
Chris@87 522 log.info(' FOUND:')
Chris@87 523
Chris@87 524 res = self.saved_results.get(self.__class__.__name__)
Chris@87 525 if self.verbosity > 0 and flag:
Chris@87 526 for k, v in res.items():
Chris@87 527 v = str(v)
Chris@87 528 if k in ['sources', 'libraries'] and len(v) > 270:
Chris@87 529 v = v[:120] + '...\n...\n...' + v[-120:]
Chris@87 530 log.info(' %s = %s', k, v)
Chris@87 531 log.info('')
Chris@87 532
Chris@87 533 return copy.deepcopy(res)
Chris@87 534
Chris@87 535 def get_paths(self, section, key):
Chris@87 536 dirs = self.cp.get(section, key).split(os.pathsep)
Chris@87 537 env_var = self.dir_env_var
Chris@87 538 if env_var:
Chris@87 539 if is_sequence(env_var):
Chris@87 540 e0 = env_var[-1]
Chris@87 541 for e in env_var:
Chris@87 542 if e in os.environ:
Chris@87 543 e0 = e
Chris@87 544 break
Chris@87 545 if not env_var[0] == e0:
Chris@87 546 log.info('Setting %s=%s' % (env_var[0], e0))
Chris@87 547 env_var = e0
Chris@87 548 if env_var and env_var in os.environ:
Chris@87 549 d = os.environ[env_var]
Chris@87 550 if d == 'None':
Chris@87 551 log.info('Disabled %s: %s',
Chris@87 552 self.__class__.__name__, '(%s is None)'
Chris@87 553 % (env_var,))
Chris@87 554 return []
Chris@87 555 if os.path.isfile(d):
Chris@87 556 dirs = [os.path.dirname(d)] + dirs
Chris@87 557 l = getattr(self, '_lib_names', [])
Chris@87 558 if len(l) == 1:
Chris@87 559 b = os.path.basename(d)
Chris@87 560 b = os.path.splitext(b)[0]
Chris@87 561 if b[:3] == 'lib':
Chris@87 562 log.info('Replacing _lib_names[0]==%r with %r' \
Chris@87 563 % (self._lib_names[0], b[3:]))
Chris@87 564 self._lib_names[0] = b[3:]
Chris@87 565 else:
Chris@87 566 ds = d.split(os.pathsep)
Chris@87 567 ds2 = []
Chris@87 568 for d in ds:
Chris@87 569 if os.path.isdir(d):
Chris@87 570 ds2.append(d)
Chris@87 571 for dd in ['include', 'lib']:
Chris@87 572 d1 = os.path.join(d, dd)
Chris@87 573 if os.path.isdir(d1):
Chris@87 574 ds2.append(d1)
Chris@87 575 dirs = ds2 + dirs
Chris@87 576 default_dirs = self.cp.get(self.section, key).split(os.pathsep)
Chris@87 577 dirs.extend(default_dirs)
Chris@87 578 ret = []
Chris@87 579 for d in dirs:
Chris@87 580 if not os.path.isdir(d):
Chris@87 581 warnings.warn('Specified path %s is invalid.' % d)
Chris@87 582 continue
Chris@87 583
Chris@87 584 if d not in ret:
Chris@87 585 ret.append(d)
Chris@87 586
Chris@87 587 log.debug('( %s = %s )', key, ':'.join(ret))
Chris@87 588 return ret
Chris@87 589
Chris@87 590 def get_lib_dirs(self, key='library_dirs'):
Chris@87 591 return self.get_paths(self.section, key)
Chris@87 592
Chris@87 593 def get_include_dirs(self, key='include_dirs'):
Chris@87 594 return self.get_paths(self.section, key)
Chris@87 595
Chris@87 596 def get_src_dirs(self, key='src_dirs'):
Chris@87 597 return self.get_paths(self.section, key)
Chris@87 598
Chris@87 599 def get_libs(self, key, default):
Chris@87 600 try:
Chris@87 601 libs = self.cp.get(self.section, key)
Chris@87 602 except NoOptionError:
Chris@87 603 if not default:
Chris@87 604 return []
Chris@87 605 if is_string(default):
Chris@87 606 return [default]
Chris@87 607 return default
Chris@87 608 return [b for b in [a.strip() for a in libs.split(',')] if b]
Chris@87 609
Chris@87 610 def get_libraries(self, key='libraries'):
Chris@87 611 return self.get_libs(key, '')
Chris@87 612
Chris@87 613 def library_extensions(self):
Chris@87 614 static_exts = ['.a']
Chris@87 615 if sys.platform == 'win32':
Chris@87 616 static_exts.append('.lib') # .lib is used by MSVC
Chris@87 617 if self.search_static_first:
Chris@87 618 exts = static_exts + [so_ext]
Chris@87 619 else:
Chris@87 620 exts = [so_ext] + static_exts
Chris@87 621 if sys.platform == 'cygwin':
Chris@87 622 exts.append('.dll.a')
Chris@87 623 if sys.platform == 'darwin':
Chris@87 624 exts.append('.dylib')
Chris@87 625 # Debian and Ubuntu added a g3f suffix to shared library to deal with
Chris@87 626 # g77 -> gfortran ABI transition
Chris@87 627 # XXX: disabled, it hides more problem than it solves.
Chris@87 628 #if sys.platform[:5] == 'linux':
Chris@87 629 # exts.append('.so.3gf')
Chris@87 630 return exts
Chris@87 631
Chris@87 632 def check_libs(self, lib_dirs, libs, opt_libs=[]):
Chris@87 633 """If static or shared libraries are available then return
Chris@87 634 their info dictionary.
Chris@87 635
Chris@87 636 Checks for all libraries as shared libraries first, then
Chris@87 637 static (or vice versa if self.search_static_first is True).
Chris@87 638 """
Chris@87 639 exts = self.library_extensions()
Chris@87 640 info = None
Chris@87 641 for ext in exts:
Chris@87 642 info = self._check_libs(lib_dirs, libs, opt_libs, [ext])
Chris@87 643 if info is not None:
Chris@87 644 break
Chris@87 645 if not info:
Chris@87 646 log.info(' libraries %s not found in %s', ','.join(libs),
Chris@87 647 lib_dirs)
Chris@87 648 return info
Chris@87 649
Chris@87 650 def check_libs2(self, lib_dirs, libs, opt_libs=[]):
Chris@87 651 """If static or shared libraries are available then return
Chris@87 652 their info dictionary.
Chris@87 653
Chris@87 654 Checks each library for shared or static.
Chris@87 655 """
Chris@87 656 exts = self.library_extensions()
Chris@87 657 info = self._check_libs(lib_dirs, libs, opt_libs, exts)
Chris@87 658 if not info:
Chris@87 659 log.info(' libraries %s not found in %s', ','.join(libs),
Chris@87 660 lib_dirs)
Chris@87 661 return info
Chris@87 662
Chris@87 663 def _lib_list(self, lib_dir, libs, exts):
Chris@87 664 assert is_string(lib_dir)
Chris@87 665 liblist = []
Chris@87 666 # under windows first try without 'lib' prefix
Chris@87 667 if sys.platform == 'win32':
Chris@87 668 lib_prefixes = ['', 'lib']
Chris@87 669 else:
Chris@87 670 lib_prefixes = ['lib']
Chris@87 671 # for each library name, see if we can find a file for it.
Chris@87 672 for l in libs:
Chris@87 673 for ext in exts:
Chris@87 674 for prefix in lib_prefixes:
Chris@87 675 p = self.combine_paths(lib_dir, prefix + l + ext)
Chris@87 676 if p:
Chris@87 677 break
Chris@87 678 if p:
Chris@87 679 assert len(p) == 1
Chris@87 680 # ??? splitext on p[0] would do this for cygwin
Chris@87 681 # doesn't seem correct
Chris@87 682 if ext == '.dll.a':
Chris@87 683 l += '.dll'
Chris@87 684 liblist.append(l)
Chris@87 685 break
Chris@87 686 return liblist
Chris@87 687
Chris@87 688 def _check_libs(self, lib_dirs, libs, opt_libs, exts):
Chris@87 689 """Find mandatory and optional libs in expected paths.
Chris@87 690
Chris@87 691 Missing optional libraries are silently forgotten.
Chris@87 692 """
Chris@87 693 # First, try to find the mandatory libraries
Chris@87 694 if is_sequence(lib_dirs):
Chris@87 695 found_libs, found_dirs = [], []
Chris@87 696 for dir_ in lib_dirs:
Chris@87 697 found_libs1 = self._lib_list(dir_, libs, exts)
Chris@87 698 # It's possible that we'll find the same library in multiple
Chris@87 699 # directories. It's also possible that we'll find some
Chris@87 700 # libraries on in directory, and some in another. So the
Chris@87 701 # obvious thing would be to use a set instead of a list, but I
Chris@87 702 # don't know if preserving order matters (does it?).
Chris@87 703 for found_lib in found_libs1:
Chris@87 704 if found_lib not in found_libs:
Chris@87 705 found_libs.append(found_lib)
Chris@87 706 if dir_ not in found_dirs:
Chris@87 707 found_dirs.append(dir_)
Chris@87 708 else:
Chris@87 709 found_libs = self._lib_list(lib_dirs, libs, exts)
Chris@87 710 found_dirs = [lib_dirs]
Chris@87 711 if len(found_libs) > 0 and len(found_libs) == len(libs):
Chris@87 712 info = {'libraries': found_libs, 'library_dirs': found_dirs}
Chris@87 713 # Now, check for optional libraries
Chris@87 714 if is_sequence(lib_dirs):
Chris@87 715 for dir_ in lib_dirs:
Chris@87 716 opt_found_libs = self._lib_list(dir_, opt_libs, exts)
Chris@87 717 if opt_found_libs:
Chris@87 718 if dir_ not in found_dirs:
Chris@87 719 found_dirs.extend(dir_)
Chris@87 720 found_libs.extend(opt_found_libs)
Chris@87 721 else:
Chris@87 722 opt_found_libs = self._lib_list(lib_dirs, opt_libs, exts)
Chris@87 723 if opt_found_libs:
Chris@87 724 found_libs.extend(opt_found_libs)
Chris@87 725 return info
Chris@87 726 else:
Chris@87 727 return None
Chris@87 728
Chris@87 729 def combine_paths(self, *args):
Chris@87 730 """Return a list of existing paths composed by all combinations
Chris@87 731 of items from the arguments.
Chris@87 732 """
Chris@87 733 return combine_paths(*args, **{'verbosity': self.verbosity})
Chris@87 734
Chris@87 735
Chris@87 736 class fft_opt_info(system_info):
Chris@87 737
Chris@87 738 def calc_info(self):
Chris@87 739 info = {}
Chris@87 740 fftw_info = get_info('fftw3') or get_info('fftw2') or get_info('dfftw')
Chris@87 741 djbfft_info = get_info('djbfft')
Chris@87 742 if fftw_info:
Chris@87 743 dict_append(info, **fftw_info)
Chris@87 744 if djbfft_info:
Chris@87 745 dict_append(info, **djbfft_info)
Chris@87 746 self.set_info(**info)
Chris@87 747 return
Chris@87 748
Chris@87 749
Chris@87 750 class fftw_info(system_info):
Chris@87 751 #variables to override
Chris@87 752 section = 'fftw'
Chris@87 753 dir_env_var = 'FFTW'
Chris@87 754 notfounderror = FFTWNotFoundError
Chris@87 755 ver_info = [{'name':'fftw3',
Chris@87 756 'libs':['fftw3'],
Chris@87 757 'includes':['fftw3.h'],
Chris@87 758 'macros':[('SCIPY_FFTW3_H', None)]},
Chris@87 759 {'name':'fftw2',
Chris@87 760 'libs':['rfftw', 'fftw'],
Chris@87 761 'includes':['fftw.h', 'rfftw.h'],
Chris@87 762 'macros':[('SCIPY_FFTW_H', None)]}]
Chris@87 763
Chris@87 764 def calc_ver_info(self, ver_param):
Chris@87 765 """Returns True on successful version detection, else False"""
Chris@87 766 lib_dirs = self.get_lib_dirs()
Chris@87 767 incl_dirs = self.get_include_dirs()
Chris@87 768 incl_dir = None
Chris@87 769 libs = self.get_libs(self.section + '_libs', ver_param['libs'])
Chris@87 770 info = self.check_libs(lib_dirs, libs)
Chris@87 771 if info is not None:
Chris@87 772 flag = 0
Chris@87 773 for d in incl_dirs:
Chris@87 774 if len(self.combine_paths(d, ver_param['includes'])) \
Chris@87 775 == len(ver_param['includes']):
Chris@87 776 dict_append(info, include_dirs=[d])
Chris@87 777 flag = 1
Chris@87 778 incl_dirs = [d]
Chris@87 779 break
Chris@87 780 if flag:
Chris@87 781 dict_append(info, define_macros=ver_param['macros'])
Chris@87 782 else:
Chris@87 783 info = None
Chris@87 784 if info is not None:
Chris@87 785 self.set_info(**info)
Chris@87 786 return True
Chris@87 787 else:
Chris@87 788 log.info(' %s not found' % (ver_param['name']))
Chris@87 789 return False
Chris@87 790
Chris@87 791 def calc_info(self):
Chris@87 792 for i in self.ver_info:
Chris@87 793 if self.calc_ver_info(i):
Chris@87 794 break
Chris@87 795
Chris@87 796
Chris@87 797 class fftw2_info(fftw_info):
Chris@87 798 #variables to override
Chris@87 799 section = 'fftw'
Chris@87 800 dir_env_var = 'FFTW'
Chris@87 801 notfounderror = FFTWNotFoundError
Chris@87 802 ver_info = [{'name':'fftw2',
Chris@87 803 'libs':['rfftw', 'fftw'],
Chris@87 804 'includes':['fftw.h', 'rfftw.h'],
Chris@87 805 'macros':[('SCIPY_FFTW_H', None)]}
Chris@87 806 ]
Chris@87 807
Chris@87 808
Chris@87 809 class fftw3_info(fftw_info):
Chris@87 810 #variables to override
Chris@87 811 section = 'fftw3'
Chris@87 812 dir_env_var = 'FFTW3'
Chris@87 813 notfounderror = FFTWNotFoundError
Chris@87 814 ver_info = [{'name':'fftw3',
Chris@87 815 'libs':['fftw3'],
Chris@87 816 'includes':['fftw3.h'],
Chris@87 817 'macros':[('SCIPY_FFTW3_H', None)]},
Chris@87 818 ]
Chris@87 819
Chris@87 820
Chris@87 821 class dfftw_info(fftw_info):
Chris@87 822 section = 'fftw'
Chris@87 823 dir_env_var = 'FFTW'
Chris@87 824 ver_info = [{'name':'dfftw',
Chris@87 825 'libs':['drfftw', 'dfftw'],
Chris@87 826 'includes':['dfftw.h', 'drfftw.h'],
Chris@87 827 'macros':[('SCIPY_DFFTW_H', None)]}]
Chris@87 828
Chris@87 829
Chris@87 830 class sfftw_info(fftw_info):
Chris@87 831 section = 'fftw'
Chris@87 832 dir_env_var = 'FFTW'
Chris@87 833 ver_info = [{'name':'sfftw',
Chris@87 834 'libs':['srfftw', 'sfftw'],
Chris@87 835 'includes':['sfftw.h', 'srfftw.h'],
Chris@87 836 'macros':[('SCIPY_SFFTW_H', None)]}]
Chris@87 837
Chris@87 838
Chris@87 839 class fftw_threads_info(fftw_info):
Chris@87 840 section = 'fftw'
Chris@87 841 dir_env_var = 'FFTW'
Chris@87 842 ver_info = [{'name':'fftw threads',
Chris@87 843 'libs':['rfftw_threads', 'fftw_threads'],
Chris@87 844 'includes':['fftw_threads.h', 'rfftw_threads.h'],
Chris@87 845 'macros':[('SCIPY_FFTW_THREADS_H', None)]}]
Chris@87 846
Chris@87 847
Chris@87 848 class dfftw_threads_info(fftw_info):
Chris@87 849 section = 'fftw'
Chris@87 850 dir_env_var = 'FFTW'
Chris@87 851 ver_info = [{'name':'dfftw threads',
Chris@87 852 'libs':['drfftw_threads', 'dfftw_threads'],
Chris@87 853 'includes':['dfftw_threads.h', 'drfftw_threads.h'],
Chris@87 854 'macros':[('SCIPY_DFFTW_THREADS_H', None)]}]
Chris@87 855
Chris@87 856
Chris@87 857 class sfftw_threads_info(fftw_info):
Chris@87 858 section = 'fftw'
Chris@87 859 dir_env_var = 'FFTW'
Chris@87 860 ver_info = [{'name':'sfftw threads',
Chris@87 861 'libs':['srfftw_threads', 'sfftw_threads'],
Chris@87 862 'includes':['sfftw_threads.h', 'srfftw_threads.h'],
Chris@87 863 'macros':[('SCIPY_SFFTW_THREADS_H', None)]}]
Chris@87 864
Chris@87 865
Chris@87 866 class djbfft_info(system_info):
Chris@87 867 section = 'djbfft'
Chris@87 868 dir_env_var = 'DJBFFT'
Chris@87 869 notfounderror = DJBFFTNotFoundError
Chris@87 870
Chris@87 871 def get_paths(self, section, key):
Chris@87 872 pre_dirs = system_info.get_paths(self, section, key)
Chris@87 873 dirs = []
Chris@87 874 for d in pre_dirs:
Chris@87 875 dirs.extend(self.combine_paths(d, ['djbfft']) + [d])
Chris@87 876 return [d for d in dirs if os.path.isdir(d)]
Chris@87 877
Chris@87 878 def calc_info(self):
Chris@87 879 lib_dirs = self.get_lib_dirs()
Chris@87 880 incl_dirs = self.get_include_dirs()
Chris@87 881 info = None
Chris@87 882 for d in lib_dirs:
Chris@87 883 p = self.combine_paths(d, ['djbfft.a'])
Chris@87 884 if p:
Chris@87 885 info = {'extra_objects': p}
Chris@87 886 break
Chris@87 887 p = self.combine_paths(d, ['libdjbfft.a', 'libdjbfft' + so_ext])
Chris@87 888 if p:
Chris@87 889 info = {'libraries': ['djbfft'], 'library_dirs': [d]}
Chris@87 890 break
Chris@87 891 if info is None:
Chris@87 892 return
Chris@87 893 for d in incl_dirs:
Chris@87 894 if len(self.combine_paths(d, ['fftc8.h', 'fftfreq.h'])) == 2:
Chris@87 895 dict_append(info, include_dirs=[d],
Chris@87 896 define_macros=[('SCIPY_DJBFFT_H', None)])
Chris@87 897 self.set_info(**info)
Chris@87 898 return
Chris@87 899 return
Chris@87 900
Chris@87 901
Chris@87 902 class mkl_info(system_info):
Chris@87 903 section = 'mkl'
Chris@87 904 dir_env_var = 'MKL'
Chris@87 905 _lib_mkl = ['mkl', 'vml', 'guide']
Chris@87 906
Chris@87 907 def get_mkl_rootdir(self):
Chris@87 908 mklroot = os.environ.get('MKLROOT', None)
Chris@87 909 if mklroot is not None:
Chris@87 910 return mklroot
Chris@87 911 paths = os.environ.get('LD_LIBRARY_PATH', '').split(os.pathsep)
Chris@87 912 ld_so_conf = '/etc/ld.so.conf'
Chris@87 913 if os.path.isfile(ld_so_conf):
Chris@87 914 for d in open(ld_so_conf, 'r'):
Chris@87 915 d = d.strip()
Chris@87 916 if d:
Chris@87 917 paths.append(d)
Chris@87 918 intel_mkl_dirs = []
Chris@87 919 for path in paths:
Chris@87 920 path_atoms = path.split(os.sep)
Chris@87 921 for m in path_atoms:
Chris@87 922 if m.startswith('mkl'):
Chris@87 923 d = os.sep.join(path_atoms[:path_atoms.index(m) + 2])
Chris@87 924 intel_mkl_dirs.append(d)
Chris@87 925 break
Chris@87 926 for d in paths:
Chris@87 927 dirs = glob(os.path.join(d, 'mkl', '*'))
Chris@87 928 dirs += glob(os.path.join(d, 'mkl*'))
Chris@87 929 for d in dirs:
Chris@87 930 if os.path.isdir(os.path.join(d, 'lib')):
Chris@87 931 return d
Chris@87 932 return None
Chris@87 933
Chris@87 934 def __init__(self):
Chris@87 935 mklroot = self.get_mkl_rootdir()
Chris@87 936 if mklroot is None:
Chris@87 937 system_info.__init__(self)
Chris@87 938 else:
Chris@87 939 from .cpuinfo import cpu
Chris@87 940 l = 'mkl' # use shared library
Chris@87 941 if cpu.is_Itanium():
Chris@87 942 plt = '64'
Chris@87 943 #l = 'mkl_ipf'
Chris@87 944 elif cpu.is_Xeon():
Chris@87 945 plt = 'em64t'
Chris@87 946 #l = 'mkl_em64t'
Chris@87 947 else:
Chris@87 948 plt = '32'
Chris@87 949 #l = 'mkl_ia32'
Chris@87 950 if l not in self._lib_mkl:
Chris@87 951 self._lib_mkl.insert(0, l)
Chris@87 952 system_info.__init__(
Chris@87 953 self,
Chris@87 954 default_lib_dirs=[os.path.join(mklroot, 'lib', plt)],
Chris@87 955 default_include_dirs=[os.path.join(mklroot, 'include')])
Chris@87 956
Chris@87 957 def calc_info(self):
Chris@87 958 lib_dirs = self.get_lib_dirs()
Chris@87 959 incl_dirs = self.get_include_dirs()
Chris@87 960 mkl_libs = self.get_libs('mkl_libs', self._lib_mkl)
Chris@87 961 info = self.check_libs2(lib_dirs, mkl_libs)
Chris@87 962 if info is None:
Chris@87 963 return
Chris@87 964 dict_append(info,
Chris@87 965 define_macros=[('SCIPY_MKL_H', None)],
Chris@87 966 include_dirs=incl_dirs)
Chris@87 967 if sys.platform == 'win32':
Chris@87 968 pass # win32 has no pthread library
Chris@87 969 else:
Chris@87 970 dict_append(info, libraries=['pthread'])
Chris@87 971 self.set_info(**info)
Chris@87 972
Chris@87 973
Chris@87 974 class lapack_mkl_info(mkl_info):
Chris@87 975
Chris@87 976 def calc_info(self):
Chris@87 977 mkl = get_info('mkl')
Chris@87 978 if not mkl:
Chris@87 979 return
Chris@87 980 if sys.platform == 'win32':
Chris@87 981 lapack_libs = self.get_libs('lapack_libs', ['mkl_lapack'])
Chris@87 982 else:
Chris@87 983 lapack_libs = self.get_libs('lapack_libs',
Chris@87 984 ['mkl_lapack32', 'mkl_lapack64'])
Chris@87 985
Chris@87 986 info = {'libraries': lapack_libs}
Chris@87 987 dict_append(info, **mkl)
Chris@87 988 self.set_info(**info)
Chris@87 989
Chris@87 990
Chris@87 991 class blas_mkl_info(mkl_info):
Chris@87 992 pass
Chris@87 993
Chris@87 994
Chris@87 995 class atlas_info(system_info):
Chris@87 996 section = 'atlas'
Chris@87 997 dir_env_var = 'ATLAS'
Chris@87 998 _lib_names = ['f77blas', 'cblas']
Chris@87 999 if sys.platform[:7] == 'freebsd':
Chris@87 1000 _lib_atlas = ['atlas_r']
Chris@87 1001 _lib_lapack = ['alapack_r']
Chris@87 1002 else:
Chris@87 1003 _lib_atlas = ['atlas']
Chris@87 1004 _lib_lapack = ['lapack']
Chris@87 1005
Chris@87 1006 notfounderror = AtlasNotFoundError
Chris@87 1007
Chris@87 1008 def get_paths(self, section, key):
Chris@87 1009 pre_dirs = system_info.get_paths(self, section, key)
Chris@87 1010 dirs = []
Chris@87 1011 for d in pre_dirs:
Chris@87 1012 dirs.extend(self.combine_paths(d, ['atlas*', 'ATLAS*',
Chris@87 1013 'sse', '3dnow', 'sse2']) + [d])
Chris@87 1014 return [d for d in dirs if os.path.isdir(d)]
Chris@87 1015
Chris@87 1016 def calc_info(self):
Chris@87 1017 lib_dirs = self.get_lib_dirs()
Chris@87 1018 info = {}
Chris@87 1019 atlas_libs = self.get_libs('atlas_libs',
Chris@87 1020 self._lib_names + self._lib_atlas)
Chris@87 1021 lapack_libs = self.get_libs('lapack_libs', self._lib_lapack)
Chris@87 1022 atlas = None
Chris@87 1023 lapack = None
Chris@87 1024 atlas_1 = None
Chris@87 1025 for d in lib_dirs:
Chris@87 1026 atlas = self.check_libs2(d, atlas_libs, [])
Chris@87 1027 lapack_atlas = self.check_libs2(d, ['lapack_atlas'], [])
Chris@87 1028 if atlas is not None:
Chris@87 1029 lib_dirs2 = [d] + self.combine_paths(d, ['atlas*', 'ATLAS*'])
Chris@87 1030 lapack = self.check_libs2(lib_dirs2, lapack_libs, [])
Chris@87 1031 if lapack is not None:
Chris@87 1032 break
Chris@87 1033 if atlas:
Chris@87 1034 atlas_1 = atlas
Chris@87 1035 log.info(self.__class__)
Chris@87 1036 if atlas is None:
Chris@87 1037 atlas = atlas_1
Chris@87 1038 if atlas is None:
Chris@87 1039 return
Chris@87 1040 include_dirs = self.get_include_dirs()
Chris@87 1041 h = (self.combine_paths(lib_dirs + include_dirs, 'cblas.h') or [None])
Chris@87 1042 h = h[0]
Chris@87 1043 if h:
Chris@87 1044 h = os.path.dirname(h)
Chris@87 1045 dict_append(info, include_dirs=[h])
Chris@87 1046 info['language'] = 'c'
Chris@87 1047 if lapack is not None:
Chris@87 1048 dict_append(info, **lapack)
Chris@87 1049 dict_append(info, **atlas)
Chris@87 1050 elif 'lapack_atlas' in atlas['libraries']:
Chris@87 1051 dict_append(info, **atlas)
Chris@87 1052 dict_append(info,
Chris@87 1053 define_macros=[('ATLAS_WITH_LAPACK_ATLAS', None)])
Chris@87 1054 self.set_info(**info)
Chris@87 1055 return
Chris@87 1056 else:
Chris@87 1057 dict_append(info, **atlas)
Chris@87 1058 dict_append(info, define_macros=[('ATLAS_WITHOUT_LAPACK', None)])
Chris@87 1059 message = """
Chris@87 1060 *********************************************************************
Chris@87 1061 Could not find lapack library within the ATLAS installation.
Chris@87 1062 *********************************************************************
Chris@87 1063 """
Chris@87 1064 warnings.warn(message)
Chris@87 1065 self.set_info(**info)
Chris@87 1066 return
Chris@87 1067
Chris@87 1068 # Check if lapack library is complete, only warn if it is not.
Chris@87 1069 lapack_dir = lapack['library_dirs'][0]
Chris@87 1070 lapack_name = lapack['libraries'][0]
Chris@87 1071 lapack_lib = None
Chris@87 1072 lib_prefixes = ['lib']
Chris@87 1073 if sys.platform == 'win32':
Chris@87 1074 lib_prefixes.append('')
Chris@87 1075 for e in self.library_extensions():
Chris@87 1076 for prefix in lib_prefixes:
Chris@87 1077 fn = os.path.join(lapack_dir, prefix + lapack_name + e)
Chris@87 1078 if os.path.exists(fn):
Chris@87 1079 lapack_lib = fn
Chris@87 1080 break
Chris@87 1081 if lapack_lib:
Chris@87 1082 break
Chris@87 1083 if lapack_lib is not None:
Chris@87 1084 sz = os.stat(lapack_lib)[6]
Chris@87 1085 if sz <= 4000 * 1024:
Chris@87 1086 message = """
Chris@87 1087 *********************************************************************
Chris@87 1088 Lapack library (from ATLAS) is probably incomplete:
Chris@87 1089 size of %s is %sk (expected >4000k)
Chris@87 1090
Chris@87 1091 Follow the instructions in the KNOWN PROBLEMS section of the file
Chris@87 1092 numpy/INSTALL.txt.
Chris@87 1093 *********************************************************************
Chris@87 1094 """ % (lapack_lib, sz / 1024)
Chris@87 1095 warnings.warn(message)
Chris@87 1096 else:
Chris@87 1097 info['language'] = 'f77'
Chris@87 1098
Chris@87 1099 atlas_version, atlas_extra_info = get_atlas_version(**atlas)
Chris@87 1100 dict_append(info, **atlas_extra_info)
Chris@87 1101
Chris@87 1102 self.set_info(**info)
Chris@87 1103
Chris@87 1104
Chris@87 1105 class atlas_blas_info(atlas_info):
Chris@87 1106 _lib_names = ['f77blas', 'cblas']
Chris@87 1107
Chris@87 1108 def calc_info(self):
Chris@87 1109 lib_dirs = self.get_lib_dirs()
Chris@87 1110 info = {}
Chris@87 1111 atlas_libs = self.get_libs('atlas_libs',
Chris@87 1112 self._lib_names + self._lib_atlas)
Chris@87 1113 atlas = self.check_libs2(lib_dirs, atlas_libs, [])
Chris@87 1114 if atlas is None:
Chris@87 1115 return
Chris@87 1116 include_dirs = self.get_include_dirs()
Chris@87 1117 h = (self.combine_paths(lib_dirs + include_dirs, 'cblas.h') or [None])
Chris@87 1118 h = h[0]
Chris@87 1119 if h:
Chris@87 1120 h = os.path.dirname(h)
Chris@87 1121 dict_append(info, include_dirs=[h])
Chris@87 1122 info['language'] = 'c'
Chris@87 1123
Chris@87 1124 atlas_version, atlas_extra_info = get_atlas_version(**atlas)
Chris@87 1125 dict_append(atlas, **atlas_extra_info)
Chris@87 1126
Chris@87 1127 dict_append(info, **atlas)
Chris@87 1128
Chris@87 1129 self.set_info(**info)
Chris@87 1130 return
Chris@87 1131
Chris@87 1132
Chris@87 1133 class atlas_threads_info(atlas_info):
Chris@87 1134 dir_env_var = ['PTATLAS', 'ATLAS']
Chris@87 1135 _lib_names = ['ptf77blas', 'ptcblas']
Chris@87 1136
Chris@87 1137
Chris@87 1138 class atlas_blas_threads_info(atlas_blas_info):
Chris@87 1139 dir_env_var = ['PTATLAS', 'ATLAS']
Chris@87 1140 _lib_names = ['ptf77blas', 'ptcblas']
Chris@87 1141
Chris@87 1142
Chris@87 1143 class lapack_atlas_info(atlas_info):
Chris@87 1144 _lib_names = ['lapack_atlas'] + atlas_info._lib_names
Chris@87 1145
Chris@87 1146
Chris@87 1147 class lapack_atlas_threads_info(atlas_threads_info):
Chris@87 1148 _lib_names = ['lapack_atlas'] + atlas_threads_info._lib_names
Chris@87 1149
Chris@87 1150
Chris@87 1151 class lapack_info(system_info):
Chris@87 1152 section = 'lapack'
Chris@87 1153 dir_env_var = 'LAPACK'
Chris@87 1154 _lib_names = ['lapack']
Chris@87 1155 notfounderror = LapackNotFoundError
Chris@87 1156
Chris@87 1157 def calc_info(self):
Chris@87 1158 lib_dirs = self.get_lib_dirs()
Chris@87 1159
Chris@87 1160 lapack_libs = self.get_libs('lapack_libs', self._lib_names)
Chris@87 1161 info = self.check_libs(lib_dirs, lapack_libs, [])
Chris@87 1162 if info is None:
Chris@87 1163 return
Chris@87 1164 info['language'] = 'f77'
Chris@87 1165 self.set_info(**info)
Chris@87 1166
Chris@87 1167
Chris@87 1168 class lapack_src_info(system_info):
Chris@87 1169 section = 'lapack_src'
Chris@87 1170 dir_env_var = 'LAPACK_SRC'
Chris@87 1171 notfounderror = LapackSrcNotFoundError
Chris@87 1172
Chris@87 1173 def get_paths(self, section, key):
Chris@87 1174 pre_dirs = system_info.get_paths(self, section, key)
Chris@87 1175 dirs = []
Chris@87 1176 for d in pre_dirs:
Chris@87 1177 dirs.extend([d] + self.combine_paths(d, ['LAPACK*/SRC', 'SRC']))
Chris@87 1178 return [d for d in dirs if os.path.isdir(d)]
Chris@87 1179
Chris@87 1180 def calc_info(self):
Chris@87 1181 src_dirs = self.get_src_dirs()
Chris@87 1182 src_dir = ''
Chris@87 1183 for d in src_dirs:
Chris@87 1184 if os.path.isfile(os.path.join(d, 'dgesv.f')):
Chris@87 1185 src_dir = d
Chris@87 1186 break
Chris@87 1187 if not src_dir:
Chris@87 1188 #XXX: Get sources from netlib. May be ask first.
Chris@87 1189 return
Chris@87 1190 # The following is extracted from LAPACK-3.0/SRC/Makefile.
Chris@87 1191 # Added missing names from lapack-lite-3.1.1/SRC/Makefile
Chris@87 1192 # while keeping removed names for Lapack-3.0 compatibility.
Chris@87 1193 allaux = '''
Chris@87 1194 ilaenv ieeeck lsame lsamen xerbla
Chris@87 1195 iparmq
Chris@87 1196 ''' # *.f
Chris@87 1197 laux = '''
Chris@87 1198 bdsdc bdsqr disna labad lacpy ladiv lae2 laebz laed0 laed1
Chris@87 1199 laed2 laed3 laed4 laed5 laed6 laed7 laed8 laed9 laeda laev2
Chris@87 1200 lagtf lagts lamch lamrg lanst lapy2 lapy3 larnv larrb larre
Chris@87 1201 larrf lartg laruv las2 lascl lasd0 lasd1 lasd2 lasd3 lasd4
Chris@87 1202 lasd5 lasd6 lasd7 lasd8 lasd9 lasda lasdq lasdt laset lasq1
Chris@87 1203 lasq2 lasq3 lasq4 lasq5 lasq6 lasr lasrt lassq lasv2 pttrf
Chris@87 1204 stebz stedc steqr sterf
Chris@87 1205
Chris@87 1206 larra larrc larrd larr larrk larrj larrr laneg laisnan isnan
Chris@87 1207 lazq3 lazq4
Chris@87 1208 ''' # [s|d]*.f
Chris@87 1209 lasrc = '''
Chris@87 1210 gbbrd gbcon gbequ gbrfs gbsv gbsvx gbtf2 gbtrf gbtrs gebak
Chris@87 1211 gebal gebd2 gebrd gecon geequ gees geesx geev geevx gegs gegv
Chris@87 1212 gehd2 gehrd gelq2 gelqf gels gelsd gelss gelsx gelsy geql2
Chris@87 1213 geqlf geqp3 geqpf geqr2 geqrf gerfs gerq2 gerqf gesc2 gesdd
Chris@87 1214 gesv gesvd gesvx getc2 getf2 getrf getri getrs ggbak ggbal
Chris@87 1215 gges ggesx ggev ggevx ggglm gghrd gglse ggqrf ggrqf ggsvd
Chris@87 1216 ggsvp gtcon gtrfs gtsv gtsvx gttrf gttrs gtts2 hgeqz hsein
Chris@87 1217 hseqr labrd lacon laein lags2 lagtm lahqr lahrd laic1 lals0
Chris@87 1218 lalsa lalsd langb lange langt lanhs lansb lansp lansy lantb
Chris@87 1219 lantp lantr lapll lapmt laqgb laqge laqp2 laqps laqsb laqsp
Chris@87 1220 laqsy lar1v lar2v larf larfb larfg larft larfx largv larrv
Chris@87 1221 lartv larz larzb larzt laswp lasyf latbs latdf latps latrd
Chris@87 1222 latrs latrz latzm lauu2 lauum pbcon pbequ pbrfs pbstf pbsv
Chris@87 1223 pbsvx pbtf2 pbtrf pbtrs pocon poequ porfs posv posvx potf2
Chris@87 1224 potrf potri potrs ppcon ppequ pprfs ppsv ppsvx pptrf pptri
Chris@87 1225 pptrs ptcon pteqr ptrfs ptsv ptsvx pttrs ptts2 spcon sprfs
Chris@87 1226 spsv spsvx sptrf sptri sptrs stegr stein sycon syrfs sysv
Chris@87 1227 sysvx sytf2 sytrf sytri sytrs tbcon tbrfs tbtrs tgevc tgex2
Chris@87 1228 tgexc tgsen tgsja tgsna tgsy2 tgsyl tpcon tprfs tptri tptrs
Chris@87 1229 trcon trevc trexc trrfs trsen trsna trsyl trti2 trtri trtrs
Chris@87 1230 tzrqf tzrzf
Chris@87 1231
Chris@87 1232 lacn2 lahr2 stemr laqr0 laqr1 laqr2 laqr3 laqr4 laqr5
Chris@87 1233 ''' # [s|c|d|z]*.f
Chris@87 1234 sd_lasrc = '''
Chris@87 1235 laexc lag2 lagv2 laln2 lanv2 laqtr lasy2 opgtr opmtr org2l
Chris@87 1236 org2r orgbr orghr orgl2 orglq orgql orgqr orgr2 orgrq orgtr
Chris@87 1237 orm2l orm2r ormbr ormhr orml2 ormlq ormql ormqr ormr2 ormr3
Chris@87 1238 ormrq ormrz ormtr rscl sbev sbevd sbevx sbgst sbgv sbgvd sbgvx
Chris@87 1239 sbtrd spev spevd spevx spgst spgv spgvd spgvx sptrd stev stevd
Chris@87 1240 stevr stevx syev syevd syevr syevx sygs2 sygst sygv sygvd
Chris@87 1241 sygvx sytd2 sytrd
Chris@87 1242 ''' # [s|d]*.f
Chris@87 1243 cz_lasrc = '''
Chris@87 1244 bdsqr hbev hbevd hbevx hbgst hbgv hbgvd hbgvx hbtrd hecon heev
Chris@87 1245 heevd heevr heevx hegs2 hegst hegv hegvd hegvx herfs hesv
Chris@87 1246 hesvx hetd2 hetf2 hetrd hetrf hetri hetrs hpcon hpev hpevd
Chris@87 1247 hpevx hpgst hpgv hpgvd hpgvx hprfs hpsv hpsvx hptrd hptrf
Chris@87 1248 hptri hptrs lacgv lacp2 lacpy lacrm lacrt ladiv laed0 laed7
Chris@87 1249 laed8 laesy laev2 lahef lanhb lanhe lanhp lanht laqhb laqhe
Chris@87 1250 laqhp larcm larnv lartg lascl laset lasr lassq pttrf rot spmv
Chris@87 1251 spr stedc steqr symv syr ung2l ung2r ungbr unghr ungl2 unglq
Chris@87 1252 ungql ungqr ungr2 ungrq ungtr unm2l unm2r unmbr unmhr unml2
Chris@87 1253 unmlq unmql unmqr unmr2 unmr3 unmrq unmrz unmtr upgtr upmtr
Chris@87 1254 ''' # [c|z]*.f
Chris@87 1255 #######
Chris@87 1256 sclaux = laux + ' econd ' # s*.f
Chris@87 1257 dzlaux = laux + ' secnd ' # d*.f
Chris@87 1258 slasrc = lasrc + sd_lasrc # s*.f
Chris@87 1259 dlasrc = lasrc + sd_lasrc # d*.f
Chris@87 1260 clasrc = lasrc + cz_lasrc + ' srot srscl ' # c*.f
Chris@87 1261 zlasrc = lasrc + cz_lasrc + ' drot drscl ' # z*.f
Chris@87 1262 oclasrc = ' icmax1 scsum1 ' # *.f
Chris@87 1263 ozlasrc = ' izmax1 dzsum1 ' # *.f
Chris@87 1264 sources = ['s%s.f' % f for f in (sclaux + slasrc).split()] \
Chris@87 1265 + ['d%s.f' % f for f in (dzlaux + dlasrc).split()] \
Chris@87 1266 + ['c%s.f' % f for f in (clasrc).split()] \
Chris@87 1267 + ['z%s.f' % f for f in (zlasrc).split()] \
Chris@87 1268 + ['%s.f' % f for f in (allaux + oclasrc + ozlasrc).split()]
Chris@87 1269 sources = [os.path.join(src_dir, f) for f in sources]
Chris@87 1270 # Lapack 3.1:
Chris@87 1271 src_dir2 = os.path.join(src_dir, '..', 'INSTALL')
Chris@87 1272 sources += [os.path.join(src_dir2, p + 'lamch.f') for p in 'sdcz']
Chris@87 1273 # Lapack 3.2.1:
Chris@87 1274 sources += [os.path.join(src_dir, p + 'larfp.f') for p in 'sdcz']
Chris@87 1275 sources += [os.path.join(src_dir, 'ila' + p + 'lr.f') for p in 'sdcz']
Chris@87 1276 sources += [os.path.join(src_dir, 'ila' + p + 'lc.f') for p in 'sdcz']
Chris@87 1277 # Should we check here actual existence of source files?
Chris@87 1278 # Yes, the file listing is different between 3.0 and 3.1
Chris@87 1279 # versions.
Chris@87 1280 sources = [f for f in sources if os.path.isfile(f)]
Chris@87 1281 info = {'sources': sources, 'language': 'f77'}
Chris@87 1282 self.set_info(**info)
Chris@87 1283
Chris@87 1284 atlas_version_c_text = r'''
Chris@87 1285 /* This file is generated from numpy/distutils/system_info.py */
Chris@87 1286 void ATL_buildinfo(void);
Chris@87 1287 int main(void) {
Chris@87 1288 ATL_buildinfo();
Chris@87 1289 return 0;
Chris@87 1290 }
Chris@87 1291 '''
Chris@87 1292
Chris@87 1293 _cached_atlas_version = {}
Chris@87 1294
Chris@87 1295
Chris@87 1296 def get_atlas_version(**config):
Chris@87 1297 libraries = config.get('libraries', [])
Chris@87 1298 library_dirs = config.get('library_dirs', [])
Chris@87 1299 key = (tuple(libraries), tuple(library_dirs))
Chris@87 1300 if key in _cached_atlas_version:
Chris@87 1301 return _cached_atlas_version[key]
Chris@87 1302 c = cmd_config(Distribution())
Chris@87 1303 atlas_version = None
Chris@87 1304 info = {}
Chris@87 1305 try:
Chris@87 1306 s, o = c.get_output(atlas_version_c_text,
Chris@87 1307 libraries=libraries, library_dirs=library_dirs,
Chris@87 1308 use_tee=(system_info.verbosity > 0))
Chris@87 1309 if s and re.search(r'undefined reference to `_gfortran', o, re.M):
Chris@87 1310 s, o = c.get_output(atlas_version_c_text,
Chris@87 1311 libraries=libraries + ['gfortran'],
Chris@87 1312 library_dirs=library_dirs,
Chris@87 1313 use_tee=(system_info.verbosity > 0))
Chris@87 1314 if not s:
Chris@87 1315 warnings.warn("""
Chris@87 1316 *****************************************************
Chris@87 1317 Linkage with ATLAS requires gfortran. Use
Chris@87 1318
Chris@87 1319 python setup.py config_fc --fcompiler=gnu95 ...
Chris@87 1320
Chris@87 1321 when building extension libraries that use ATLAS.
Chris@87 1322 Make sure that -lgfortran is used for C++ extensions.
Chris@87 1323 *****************************************************
Chris@87 1324 """)
Chris@87 1325 dict_append(info, language='f90',
Chris@87 1326 define_macros=[('ATLAS_REQUIRES_GFORTRAN', None)])
Chris@87 1327 except Exception: # failed to get version from file -- maybe on Windows
Chris@87 1328 # look at directory name
Chris@87 1329 for o in library_dirs:
Chris@87 1330 m = re.search(r'ATLAS_(?P<version>\d+[.]\d+[.]\d+)_', o)
Chris@87 1331 if m:
Chris@87 1332 atlas_version = m.group('version')
Chris@87 1333 if atlas_version is not None:
Chris@87 1334 break
Chris@87 1335
Chris@87 1336 # final choice --- look at ATLAS_VERSION environment
Chris@87 1337 # variable
Chris@87 1338 if atlas_version is None:
Chris@87 1339 atlas_version = os.environ.get('ATLAS_VERSION', None)
Chris@87 1340 if atlas_version:
Chris@87 1341 dict_append(info, define_macros=[(
Chris@87 1342 'ATLAS_INFO', '"\\"%s\\""' % atlas_version)
Chris@87 1343 ])
Chris@87 1344 else:
Chris@87 1345 dict_append(info, define_macros=[('NO_ATLAS_INFO', -1)])
Chris@87 1346 return atlas_version or '?.?.?', info
Chris@87 1347
Chris@87 1348 if not s:
Chris@87 1349 m = re.search(r'ATLAS version (?P<version>\d+[.]\d+[.]\d+)', o)
Chris@87 1350 if m:
Chris@87 1351 atlas_version = m.group('version')
Chris@87 1352 if atlas_version is None:
Chris@87 1353 if re.search(r'undefined symbol: ATL_buildinfo', o, re.M):
Chris@87 1354 atlas_version = '3.2.1_pre3.3.6'
Chris@87 1355 else:
Chris@87 1356 log.info('Status: %d', s)
Chris@87 1357 log.info('Output: %s', o)
Chris@87 1358
Chris@87 1359 if atlas_version == '3.2.1_pre3.3.6':
Chris@87 1360 dict_append(info, define_macros=[('NO_ATLAS_INFO', -2)])
Chris@87 1361 else:
Chris@87 1362 dict_append(info, define_macros=[(
Chris@87 1363 'ATLAS_INFO', '"\\"%s\\""' % atlas_version)
Chris@87 1364 ])
Chris@87 1365 result = _cached_atlas_version[key] = atlas_version, info
Chris@87 1366 return result
Chris@87 1367
Chris@87 1368
Chris@87 1369
Chris@87 1370 class lapack_opt_info(system_info):
Chris@87 1371
Chris@87 1372 notfounderror = LapackNotFoundError
Chris@87 1373
Chris@87 1374 def calc_info(self):
Chris@87 1375
Chris@87 1376 openblas_info = get_info('openblas_lapack')
Chris@87 1377 if openblas_info:
Chris@87 1378 self.set_info(**openblas_info)
Chris@87 1379 return
Chris@87 1380
Chris@87 1381 lapack_mkl_info = get_info('lapack_mkl')
Chris@87 1382 if lapack_mkl_info:
Chris@87 1383 self.set_info(**lapack_mkl_info)
Chris@87 1384 return
Chris@87 1385
Chris@87 1386 atlas_info = get_info('atlas_threads')
Chris@87 1387 if not atlas_info:
Chris@87 1388 atlas_info = get_info('atlas')
Chris@87 1389
Chris@87 1390 if sys.platform == 'darwin' and not atlas_info:
Chris@87 1391 # Use the system lapack from Accelerate or vecLib under OSX
Chris@87 1392 args = []
Chris@87 1393 link_args = []
Chris@87 1394 if get_platform()[-4:] == 'i386' or 'intel' in get_platform() or \
Chris@87 1395 'x86_64' in get_platform() or \
Chris@87 1396 'i386' in platform.platform():
Chris@87 1397 intel = 1
Chris@87 1398 else:
Chris@87 1399 intel = 0
Chris@87 1400 if os.path.exists('/System/Library/Frameworks'
Chris@87 1401 '/Accelerate.framework/'):
Chris@87 1402 if intel:
Chris@87 1403 args.extend(['-msse3', '-DAPPLE_ACCELERATE_SGEMV_PATCH'])
Chris@87 1404 else:
Chris@87 1405 args.extend(['-faltivec'])
Chris@87 1406 link_args.extend(['-Wl,-framework', '-Wl,Accelerate'])
Chris@87 1407 elif os.path.exists('/System/Library/Frameworks'
Chris@87 1408 '/vecLib.framework/'):
Chris@87 1409 if intel:
Chris@87 1410 args.extend(['-msse3'])
Chris@87 1411 else:
Chris@87 1412 args.extend(['-faltivec'])
Chris@87 1413 link_args.extend(['-Wl,-framework', '-Wl,vecLib'])
Chris@87 1414 if args:
Chris@87 1415 self.set_info(extra_compile_args=args,
Chris@87 1416 extra_link_args=link_args,
Chris@87 1417 define_macros=[('NO_ATLAS_INFO', 3)])
Chris@87 1418 return
Chris@87 1419
Chris@87 1420 #atlas_info = {} ## uncomment for testing
Chris@87 1421 need_lapack = 0
Chris@87 1422 need_blas = 0
Chris@87 1423 info = {}
Chris@87 1424 if atlas_info:
Chris@87 1425 l = atlas_info.get('define_macros', [])
Chris@87 1426 if ('ATLAS_WITH_LAPACK_ATLAS', None) in l \
Chris@87 1427 or ('ATLAS_WITHOUT_LAPACK', None) in l:
Chris@87 1428 need_lapack = 1
Chris@87 1429 info = atlas_info
Chris@87 1430
Chris@87 1431 else:
Chris@87 1432 warnings.warn(AtlasNotFoundError.__doc__)
Chris@87 1433 need_blas = 1
Chris@87 1434 need_lapack = 1
Chris@87 1435 dict_append(info, define_macros=[('NO_ATLAS_INFO', 1)])
Chris@87 1436
Chris@87 1437 if need_lapack:
Chris@87 1438 lapack_info = get_info('lapack')
Chris@87 1439 #lapack_info = {} ## uncomment for testing
Chris@87 1440 if lapack_info:
Chris@87 1441 dict_append(info, **lapack_info)
Chris@87 1442 else:
Chris@87 1443 warnings.warn(LapackNotFoundError.__doc__)
Chris@87 1444 lapack_src_info = get_info('lapack_src')
Chris@87 1445 if not lapack_src_info:
Chris@87 1446 warnings.warn(LapackSrcNotFoundError.__doc__)
Chris@87 1447 return
Chris@87 1448 dict_append(info, libraries=[('flapack_src', lapack_src_info)])
Chris@87 1449
Chris@87 1450 if need_blas:
Chris@87 1451 blas_info = get_info('blas')
Chris@87 1452 #blas_info = {} ## uncomment for testing
Chris@87 1453 if blas_info:
Chris@87 1454 dict_append(info, **blas_info)
Chris@87 1455 else:
Chris@87 1456 warnings.warn(BlasNotFoundError.__doc__)
Chris@87 1457 blas_src_info = get_info('blas_src')
Chris@87 1458 if not blas_src_info:
Chris@87 1459 warnings.warn(BlasSrcNotFoundError.__doc__)
Chris@87 1460 return
Chris@87 1461 dict_append(info, libraries=[('fblas_src', blas_src_info)])
Chris@87 1462
Chris@87 1463 self.set_info(**info)
Chris@87 1464 return
Chris@87 1465
Chris@87 1466
Chris@87 1467 class blas_opt_info(system_info):
Chris@87 1468
Chris@87 1469 notfounderror = BlasNotFoundError
Chris@87 1470
Chris@87 1471 def calc_info(self):
Chris@87 1472
Chris@87 1473 blas_mkl_info = get_info('blas_mkl')
Chris@87 1474 if blas_mkl_info:
Chris@87 1475 self.set_info(**blas_mkl_info)
Chris@87 1476 return
Chris@87 1477
Chris@87 1478 openblas_info = get_info('openblas')
Chris@87 1479 if openblas_info:
Chris@87 1480 self.set_info(**openblas_info)
Chris@87 1481 return
Chris@87 1482
Chris@87 1483 atlas_info = get_info('atlas_blas_threads')
Chris@87 1484 if not atlas_info:
Chris@87 1485 atlas_info = get_info('atlas_blas')
Chris@87 1486
Chris@87 1487 if sys.platform == 'darwin' and not atlas_info:
Chris@87 1488 # Use the system BLAS from Accelerate or vecLib under OSX
Chris@87 1489 args = []
Chris@87 1490 link_args = []
Chris@87 1491 if get_platform()[-4:] == 'i386' or 'intel' in get_platform() or \
Chris@87 1492 'x86_64' in get_platform() or \
Chris@87 1493 'i386' in platform.platform():
Chris@87 1494 intel = 1
Chris@87 1495 else:
Chris@87 1496 intel = 0
Chris@87 1497 if os.path.exists('/System/Library/Frameworks'
Chris@87 1498 '/Accelerate.framework/'):
Chris@87 1499 if intel:
Chris@87 1500 args.extend(['-msse3', '-DAPPLE_ACCELERATE_SGEMV_PATCH'])
Chris@87 1501 else:
Chris@87 1502 args.extend(['-faltivec'])
Chris@87 1503 args.extend([
Chris@87 1504 '-I/System/Library/Frameworks/vecLib.framework/Headers'])
Chris@87 1505 link_args.extend(['-Wl,-framework', '-Wl,Accelerate'])
Chris@87 1506 elif os.path.exists('/System/Library/Frameworks'
Chris@87 1507 '/vecLib.framework/'):
Chris@87 1508 if intel:
Chris@87 1509 args.extend(['-msse3'])
Chris@87 1510 else:
Chris@87 1511 args.extend(['-faltivec'])
Chris@87 1512 args.extend([
Chris@87 1513 '-I/System/Library/Frameworks/vecLib.framework/Headers'])
Chris@87 1514 link_args.extend(['-Wl,-framework', '-Wl,vecLib'])
Chris@87 1515 if args:
Chris@87 1516 self.set_info(extra_compile_args=args,
Chris@87 1517 extra_link_args=link_args,
Chris@87 1518 define_macros=[('NO_ATLAS_INFO', 3)])
Chris@87 1519 return
Chris@87 1520
Chris@87 1521 need_blas = 0
Chris@87 1522 info = {}
Chris@87 1523 if atlas_info:
Chris@87 1524 info = atlas_info
Chris@87 1525 else:
Chris@87 1526 warnings.warn(AtlasNotFoundError.__doc__)
Chris@87 1527 need_blas = 1
Chris@87 1528 dict_append(info, define_macros=[('NO_ATLAS_INFO', 1)])
Chris@87 1529
Chris@87 1530 if need_blas:
Chris@87 1531 blas_info = get_info('blas')
Chris@87 1532 if blas_info:
Chris@87 1533 dict_append(info, **blas_info)
Chris@87 1534 else:
Chris@87 1535 warnings.warn(BlasNotFoundError.__doc__)
Chris@87 1536 blas_src_info = get_info('blas_src')
Chris@87 1537 if not blas_src_info:
Chris@87 1538 warnings.warn(BlasSrcNotFoundError.__doc__)
Chris@87 1539 return
Chris@87 1540 dict_append(info, libraries=[('fblas_src', blas_src_info)])
Chris@87 1541
Chris@87 1542 self.set_info(**info)
Chris@87 1543 return
Chris@87 1544
Chris@87 1545
Chris@87 1546 class blas_info(system_info):
Chris@87 1547 section = 'blas'
Chris@87 1548 dir_env_var = 'BLAS'
Chris@87 1549 _lib_names = ['blas']
Chris@87 1550 notfounderror = BlasNotFoundError
Chris@87 1551
Chris@87 1552 def calc_info(self):
Chris@87 1553 lib_dirs = self.get_lib_dirs()
Chris@87 1554
Chris@87 1555 blas_libs = self.get_libs('blas_libs', self._lib_names)
Chris@87 1556 info = self.check_libs(lib_dirs, blas_libs, [])
Chris@87 1557 if info is None:
Chris@87 1558 return
Chris@87 1559 info['language'] = 'f77' # XXX: is it generally true?
Chris@87 1560 self.set_info(**info)
Chris@87 1561
Chris@87 1562
Chris@87 1563 class openblas_info(blas_info):
Chris@87 1564 section = 'openblas'
Chris@87 1565 dir_env_var = 'OPENBLAS'
Chris@87 1566 _lib_names = ['openblas']
Chris@87 1567 notfounderror = BlasNotFoundError
Chris@87 1568
Chris@87 1569 def check_embedded_lapack(self, info):
Chris@87 1570 return True
Chris@87 1571
Chris@87 1572 def calc_info(self):
Chris@87 1573 lib_dirs = self.get_lib_dirs()
Chris@87 1574
Chris@87 1575 openblas_libs = self.get_libs('libraries', self._lib_names)
Chris@87 1576 if openblas_libs == self._lib_names: # backward compat with 1.8.0
Chris@87 1577 openblas_libs = self.get_libs('openblas_libs', self._lib_names)
Chris@87 1578 info = self.check_libs(lib_dirs, openblas_libs, [])
Chris@87 1579 if info is None:
Chris@87 1580 return
Chris@87 1581
Chris@87 1582 if not self.check_embedded_lapack(info):
Chris@87 1583 return None
Chris@87 1584
Chris@87 1585 info['language'] = 'f77' # XXX: is it generally true?
Chris@87 1586 self.set_info(**info)
Chris@87 1587
Chris@87 1588
Chris@87 1589 class openblas_lapack_info(openblas_info):
Chris@87 1590 section = 'openblas'
Chris@87 1591 dir_env_var = 'OPENBLAS'
Chris@87 1592 _lib_names = ['openblas']
Chris@87 1593 notfounderror = BlasNotFoundError
Chris@87 1594
Chris@87 1595 def check_embedded_lapack(self, info):
Chris@87 1596 res = False
Chris@87 1597 c = distutils.ccompiler.new_compiler()
Chris@87 1598 tmpdir = tempfile.mkdtemp()
Chris@87 1599 s = """void zungqr();
Chris@87 1600 int main(int argc, const char *argv[])
Chris@87 1601 {
Chris@87 1602 zungqr_();
Chris@87 1603 return 0;
Chris@87 1604 }"""
Chris@87 1605 src = os.path.join(tmpdir, 'source.c')
Chris@87 1606 out = os.path.join(tmpdir, 'a.out')
Chris@87 1607 try:
Chris@87 1608 with open(src, 'wt') as f:
Chris@87 1609 f.write(s)
Chris@87 1610 obj = c.compile([src], output_dir=tmpdir)
Chris@87 1611 try:
Chris@87 1612 c.link_executable(obj, out, libraries=info['libraries'],
Chris@87 1613 library_dirs=info['library_dirs'])
Chris@87 1614 res = True
Chris@87 1615 except distutils.ccompiler.LinkError:
Chris@87 1616 res = False
Chris@87 1617 finally:
Chris@87 1618 shutil.rmtree(tmpdir)
Chris@87 1619 return res
Chris@87 1620
Chris@87 1621
Chris@87 1622 class blas_src_info(system_info):
Chris@87 1623 section = 'blas_src'
Chris@87 1624 dir_env_var = 'BLAS_SRC'
Chris@87 1625 notfounderror = BlasSrcNotFoundError
Chris@87 1626
Chris@87 1627 def get_paths(self, section, key):
Chris@87 1628 pre_dirs = system_info.get_paths(self, section, key)
Chris@87 1629 dirs = []
Chris@87 1630 for d in pre_dirs:
Chris@87 1631 dirs.extend([d] + self.combine_paths(d, ['blas']))
Chris@87 1632 return [d for d in dirs if os.path.isdir(d)]
Chris@87 1633
Chris@87 1634 def calc_info(self):
Chris@87 1635 src_dirs = self.get_src_dirs()
Chris@87 1636 src_dir = ''
Chris@87 1637 for d in src_dirs:
Chris@87 1638 if os.path.isfile(os.path.join(d, 'daxpy.f')):
Chris@87 1639 src_dir = d
Chris@87 1640 break
Chris@87 1641 if not src_dir:
Chris@87 1642 #XXX: Get sources from netlib. May be ask first.
Chris@87 1643 return
Chris@87 1644 blas1 = '''
Chris@87 1645 caxpy csscal dnrm2 dzasum saxpy srotg zdotc ccopy cswap drot
Chris@87 1646 dznrm2 scasum srotm zdotu cdotc dasum drotg icamax scnrm2
Chris@87 1647 srotmg zdrot cdotu daxpy drotm idamax scopy sscal zdscal crotg
Chris@87 1648 dcabs1 drotmg isamax sdot sswap zrotg cscal dcopy dscal izamax
Chris@87 1649 snrm2 zaxpy zscal csrot ddot dswap sasum srot zcopy zswap
Chris@87 1650 scabs1
Chris@87 1651 '''
Chris@87 1652 blas2 = '''
Chris@87 1653 cgbmv chpmv ctrsv dsymv dtrsv sspr2 strmv zhemv ztpmv cgemv
Chris@87 1654 chpr dgbmv dsyr lsame ssymv strsv zher ztpsv cgerc chpr2 dgemv
Chris@87 1655 dsyr2 sgbmv ssyr xerbla zher2 ztrmv cgeru ctbmv dger dtbmv
Chris@87 1656 sgemv ssyr2 zgbmv zhpmv ztrsv chbmv ctbsv dsbmv dtbsv sger
Chris@87 1657 stbmv zgemv zhpr chemv ctpmv dspmv dtpmv ssbmv stbsv zgerc
Chris@87 1658 zhpr2 cher ctpsv dspr dtpsv sspmv stpmv zgeru ztbmv cher2
Chris@87 1659 ctrmv dspr2 dtrmv sspr stpsv zhbmv ztbsv
Chris@87 1660 '''
Chris@87 1661 blas3 = '''
Chris@87 1662 cgemm csymm ctrsm dsyrk sgemm strmm zhemm zsyr2k chemm csyr2k
Chris@87 1663 dgemm dtrmm ssymm strsm zher2k zsyrk cher2k csyrk dsymm dtrsm
Chris@87 1664 ssyr2k zherk ztrmm cherk ctrmm dsyr2k ssyrk zgemm zsymm ztrsm
Chris@87 1665 '''
Chris@87 1666 sources = [os.path.join(src_dir, f + '.f') \
Chris@87 1667 for f in (blas1 + blas2 + blas3).split()]
Chris@87 1668 #XXX: should we check here actual existence of source files?
Chris@87 1669 sources = [f for f in sources if os.path.isfile(f)]
Chris@87 1670 info = {'sources': sources, 'language': 'f77'}
Chris@87 1671 self.set_info(**info)
Chris@87 1672
Chris@87 1673
Chris@87 1674 class x11_info(system_info):
Chris@87 1675 section = 'x11'
Chris@87 1676 notfounderror = X11NotFoundError
Chris@87 1677
Chris@87 1678 def __init__(self):
Chris@87 1679 system_info.__init__(self,
Chris@87 1680 default_lib_dirs=default_x11_lib_dirs,
Chris@87 1681 default_include_dirs=default_x11_include_dirs)
Chris@87 1682
Chris@87 1683 def calc_info(self):
Chris@87 1684 if sys.platform in ['win32']:
Chris@87 1685 return
Chris@87 1686 lib_dirs = self.get_lib_dirs()
Chris@87 1687 include_dirs = self.get_include_dirs()
Chris@87 1688 x11_libs = self.get_libs('x11_libs', ['X11'])
Chris@87 1689 info = self.check_libs(lib_dirs, x11_libs, [])
Chris@87 1690 if info is None:
Chris@87 1691 return
Chris@87 1692 inc_dir = None
Chris@87 1693 for d in include_dirs:
Chris@87 1694 if self.combine_paths(d, 'X11/X.h'):
Chris@87 1695 inc_dir = d
Chris@87 1696 break
Chris@87 1697 if inc_dir is not None:
Chris@87 1698 dict_append(info, include_dirs=[inc_dir])
Chris@87 1699 self.set_info(**info)
Chris@87 1700
Chris@87 1701
Chris@87 1702 class _numpy_info(system_info):
Chris@87 1703 section = 'Numeric'
Chris@87 1704 modulename = 'Numeric'
Chris@87 1705 notfounderror = NumericNotFoundError
Chris@87 1706
Chris@87 1707 def __init__(self):
Chris@87 1708 include_dirs = []
Chris@87 1709 try:
Chris@87 1710 module = __import__(self.modulename)
Chris@87 1711 prefix = []
Chris@87 1712 for name in module.__file__.split(os.sep):
Chris@87 1713 if name == 'lib':
Chris@87 1714 break
Chris@87 1715 prefix.append(name)
Chris@87 1716
Chris@87 1717 # Ask numpy for its own include path before attempting
Chris@87 1718 # anything else
Chris@87 1719 try:
Chris@87 1720 include_dirs.append(getattr(module, 'get_include')())
Chris@87 1721 except AttributeError:
Chris@87 1722 pass
Chris@87 1723
Chris@87 1724 include_dirs.append(distutils.sysconfig.get_python_inc(
Chris@87 1725 prefix=os.sep.join(prefix)))
Chris@87 1726 except ImportError:
Chris@87 1727 pass
Chris@87 1728 py_incl_dir = distutils.sysconfig.get_python_inc()
Chris@87 1729 include_dirs.append(py_incl_dir)
Chris@87 1730 py_pincl_dir = distutils.sysconfig.get_python_inc(plat_specific=True)
Chris@87 1731 if py_pincl_dir not in include_dirs:
Chris@87 1732 include_dirs.append(py_pincl_dir)
Chris@87 1733 for d in default_include_dirs:
Chris@87 1734 d = os.path.join(d, os.path.basename(py_incl_dir))
Chris@87 1735 if d not in include_dirs:
Chris@87 1736 include_dirs.append(d)
Chris@87 1737 system_info.__init__(self,
Chris@87 1738 default_lib_dirs=[],
Chris@87 1739 default_include_dirs=include_dirs)
Chris@87 1740
Chris@87 1741 def calc_info(self):
Chris@87 1742 try:
Chris@87 1743 module = __import__(self.modulename)
Chris@87 1744 except ImportError:
Chris@87 1745 return
Chris@87 1746 info = {}
Chris@87 1747 macros = []
Chris@87 1748 for v in ['__version__', 'version']:
Chris@87 1749 vrs = getattr(module, v, None)
Chris@87 1750 if vrs is None:
Chris@87 1751 continue
Chris@87 1752 macros = [(self.modulename.upper() + '_VERSION',
Chris@87 1753 '"\\"%s\\""' % (vrs)),
Chris@87 1754 (self.modulename.upper(), None)]
Chris@87 1755 break
Chris@87 1756 ## try:
Chris@87 1757 ## macros.append(
Chris@87 1758 ## (self.modulename.upper()+'_VERSION_HEX',
Chris@87 1759 ## hex(vstr2hex(module.__version__))),
Chris@87 1760 ## )
Chris@87 1761 ## except Exception as msg:
Chris@87 1762 ## print msg
Chris@87 1763 dict_append(info, define_macros=macros)
Chris@87 1764 include_dirs = self.get_include_dirs()
Chris@87 1765 inc_dir = None
Chris@87 1766 for d in include_dirs:
Chris@87 1767 if self.combine_paths(d,
Chris@87 1768 os.path.join(self.modulename,
Chris@87 1769 'arrayobject.h')):
Chris@87 1770 inc_dir = d
Chris@87 1771 break
Chris@87 1772 if inc_dir is not None:
Chris@87 1773 dict_append(info, include_dirs=[inc_dir])
Chris@87 1774 if info:
Chris@87 1775 self.set_info(**info)
Chris@87 1776 return
Chris@87 1777
Chris@87 1778
Chris@87 1779 class numarray_info(_numpy_info):
Chris@87 1780 section = 'numarray'
Chris@87 1781 modulename = 'numarray'
Chris@87 1782
Chris@87 1783
Chris@87 1784 class Numeric_info(_numpy_info):
Chris@87 1785 section = 'Numeric'
Chris@87 1786 modulename = 'Numeric'
Chris@87 1787
Chris@87 1788
Chris@87 1789 class numpy_info(_numpy_info):
Chris@87 1790 section = 'numpy'
Chris@87 1791 modulename = 'numpy'
Chris@87 1792
Chris@87 1793
Chris@87 1794 class numerix_info(system_info):
Chris@87 1795 section = 'numerix'
Chris@87 1796
Chris@87 1797 def calc_info(self):
Chris@87 1798 which = None, None
Chris@87 1799 if os.getenv("NUMERIX"):
Chris@87 1800 which = os.getenv("NUMERIX"), "environment var"
Chris@87 1801 # If all the above fail, default to numpy.
Chris@87 1802 if which[0] is None:
Chris@87 1803 which = "numpy", "defaulted"
Chris@87 1804 try:
Chris@87 1805 import numpy
Chris@87 1806 which = "numpy", "defaulted"
Chris@87 1807 except ImportError:
Chris@87 1808 msg1 = str(get_exception())
Chris@87 1809 try:
Chris@87 1810 import Numeric
Chris@87 1811 which = "numeric", "defaulted"
Chris@87 1812 except ImportError:
Chris@87 1813 msg2 = str(get_exception())
Chris@87 1814 try:
Chris@87 1815 import numarray
Chris@87 1816 which = "numarray", "defaulted"
Chris@87 1817 except ImportError:
Chris@87 1818 msg3 = str(get_exception())
Chris@87 1819 log.info(msg1)
Chris@87 1820 log.info(msg2)
Chris@87 1821 log.info(msg3)
Chris@87 1822 which = which[0].strip().lower(), which[1]
Chris@87 1823 if which[0] not in ["numeric", "numarray", "numpy"]:
Chris@87 1824 raise ValueError("numerix selector must be either 'Numeric' "
Chris@87 1825 "or 'numarray' or 'numpy' but the value obtained"
Chris@87 1826 " from the %s was '%s'." % (which[1], which[0]))
Chris@87 1827 os.environ['NUMERIX'] = which[0]
Chris@87 1828 self.set_info(**get_info(which[0]))
Chris@87 1829
Chris@87 1830
Chris@87 1831 class f2py_info(system_info):
Chris@87 1832 def calc_info(self):
Chris@87 1833 try:
Chris@87 1834 import numpy.f2py as f2py
Chris@87 1835 except ImportError:
Chris@87 1836 return
Chris@87 1837 f2py_dir = os.path.join(os.path.dirname(f2py.__file__), 'src')
Chris@87 1838 self.set_info(sources=[os.path.join(f2py_dir, 'fortranobject.c')],
Chris@87 1839 include_dirs=[f2py_dir])
Chris@87 1840 return
Chris@87 1841
Chris@87 1842
Chris@87 1843 class boost_python_info(system_info):
Chris@87 1844 section = 'boost_python'
Chris@87 1845 dir_env_var = 'BOOST'
Chris@87 1846
Chris@87 1847 def get_paths(self, section, key):
Chris@87 1848 pre_dirs = system_info.get_paths(self, section, key)
Chris@87 1849 dirs = []
Chris@87 1850 for d in pre_dirs:
Chris@87 1851 dirs.extend([d] + self.combine_paths(d, ['boost*']))
Chris@87 1852 return [d for d in dirs if os.path.isdir(d)]
Chris@87 1853
Chris@87 1854 def calc_info(self):
Chris@87 1855 src_dirs = self.get_src_dirs()
Chris@87 1856 src_dir = ''
Chris@87 1857 for d in src_dirs:
Chris@87 1858 if os.path.isfile(os.path.join(d, 'libs', 'python', 'src',
Chris@87 1859 'module.cpp')):
Chris@87 1860 src_dir = d
Chris@87 1861 break
Chris@87 1862 if not src_dir:
Chris@87 1863 return
Chris@87 1864 py_incl_dirs = [distutils.sysconfig.get_python_inc()]
Chris@87 1865 py_pincl_dir = distutils.sysconfig.get_python_inc(plat_specific=True)
Chris@87 1866 if py_pincl_dir not in py_incl_dirs:
Chris@87 1867 py_incl_dirs.append(py_pincl_dir)
Chris@87 1868 srcs_dir = os.path.join(src_dir, 'libs', 'python', 'src')
Chris@87 1869 bpl_srcs = glob(os.path.join(srcs_dir, '*.cpp'))
Chris@87 1870 bpl_srcs += glob(os.path.join(srcs_dir, '*', '*.cpp'))
Chris@87 1871 info = {'libraries': [('boost_python_src',
Chris@87 1872 {'include_dirs': [src_dir] + py_incl_dirs,
Chris@87 1873 'sources':bpl_srcs}
Chris@87 1874 )],
Chris@87 1875 'include_dirs': [src_dir],
Chris@87 1876 }
Chris@87 1877 if info:
Chris@87 1878 self.set_info(**info)
Chris@87 1879 return
Chris@87 1880
Chris@87 1881
Chris@87 1882 class agg2_info(system_info):
Chris@87 1883 section = 'agg2'
Chris@87 1884 dir_env_var = 'AGG2'
Chris@87 1885
Chris@87 1886 def get_paths(self, section, key):
Chris@87 1887 pre_dirs = system_info.get_paths(self, section, key)
Chris@87 1888 dirs = []
Chris@87 1889 for d in pre_dirs:
Chris@87 1890 dirs.extend([d] + self.combine_paths(d, ['agg2*']))
Chris@87 1891 return [d for d in dirs if os.path.isdir(d)]
Chris@87 1892
Chris@87 1893 def calc_info(self):
Chris@87 1894 src_dirs = self.get_src_dirs()
Chris@87 1895 src_dir = ''
Chris@87 1896 for d in src_dirs:
Chris@87 1897 if os.path.isfile(os.path.join(d, 'src', 'agg_affine_matrix.cpp')):
Chris@87 1898 src_dir = d
Chris@87 1899 break
Chris@87 1900 if not src_dir:
Chris@87 1901 return
Chris@87 1902 if sys.platform == 'win32':
Chris@87 1903 agg2_srcs = glob(os.path.join(src_dir, 'src', 'platform',
Chris@87 1904 'win32', 'agg_win32_bmp.cpp'))
Chris@87 1905 else:
Chris@87 1906 agg2_srcs = glob(os.path.join(src_dir, 'src', '*.cpp'))
Chris@87 1907 agg2_srcs += [os.path.join(src_dir, 'src', 'platform',
Chris@87 1908 'X11',
Chris@87 1909 'agg_platform_support.cpp')]
Chris@87 1910
Chris@87 1911 info = {'libraries':
Chris@87 1912 [('agg2_src',
Chris@87 1913 {'sources': agg2_srcs,
Chris@87 1914 'include_dirs': [os.path.join(src_dir, 'include')],
Chris@87 1915 }
Chris@87 1916 )],
Chris@87 1917 'include_dirs': [os.path.join(src_dir, 'include')],
Chris@87 1918 }
Chris@87 1919 if info:
Chris@87 1920 self.set_info(**info)
Chris@87 1921 return
Chris@87 1922
Chris@87 1923
Chris@87 1924 class _pkg_config_info(system_info):
Chris@87 1925 section = None
Chris@87 1926 config_env_var = 'PKG_CONFIG'
Chris@87 1927 default_config_exe = 'pkg-config'
Chris@87 1928 append_config_exe = ''
Chris@87 1929 version_macro_name = None
Chris@87 1930 release_macro_name = None
Chris@87 1931 version_flag = '--modversion'
Chris@87 1932 cflags_flag = '--cflags'
Chris@87 1933
Chris@87 1934 def get_config_exe(self):
Chris@87 1935 if self.config_env_var in os.environ:
Chris@87 1936 return os.environ[self.config_env_var]
Chris@87 1937 return self.default_config_exe
Chris@87 1938
Chris@87 1939 def get_config_output(self, config_exe, option):
Chris@87 1940 cmd = config_exe + ' ' + self.append_config_exe + ' ' + option
Chris@87 1941 s, o = exec_command(cmd, use_tee=0)
Chris@87 1942 if not s:
Chris@87 1943 return o
Chris@87 1944
Chris@87 1945 def calc_info(self):
Chris@87 1946 config_exe = find_executable(self.get_config_exe())
Chris@87 1947 if not config_exe:
Chris@87 1948 log.warn('File not found: %s. Cannot determine %s info.' \
Chris@87 1949 % (config_exe, self.section))
Chris@87 1950 return
Chris@87 1951 info = {}
Chris@87 1952 macros = []
Chris@87 1953 libraries = []
Chris@87 1954 library_dirs = []
Chris@87 1955 include_dirs = []
Chris@87 1956 extra_link_args = []
Chris@87 1957 extra_compile_args = []
Chris@87 1958 version = self.get_config_output(config_exe, self.version_flag)
Chris@87 1959 if version:
Chris@87 1960 macros.append((self.__class__.__name__.split('.')[-1].upper(),
Chris@87 1961 '"\\"%s\\""' % (version)))
Chris@87 1962 if self.version_macro_name:
Chris@87 1963 macros.append((self.version_macro_name + '_%s'
Chris@87 1964 % (version.replace('.', '_')), None))
Chris@87 1965 if self.release_macro_name:
Chris@87 1966 release = self.get_config_output(config_exe, '--release')
Chris@87 1967 if release:
Chris@87 1968 macros.append((self.release_macro_name + '_%s'
Chris@87 1969 % (release.replace('.', '_')), None))
Chris@87 1970 opts = self.get_config_output(config_exe, '--libs')
Chris@87 1971 if opts:
Chris@87 1972 for opt in opts.split():
Chris@87 1973 if opt[:2] == '-l':
Chris@87 1974 libraries.append(opt[2:])
Chris@87 1975 elif opt[:2] == '-L':
Chris@87 1976 library_dirs.append(opt[2:])
Chris@87 1977 else:
Chris@87 1978 extra_link_args.append(opt)
Chris@87 1979 opts = self.get_config_output(config_exe, self.cflags_flag)
Chris@87 1980 if opts:
Chris@87 1981 for opt in opts.split():
Chris@87 1982 if opt[:2] == '-I':
Chris@87 1983 include_dirs.append(opt[2:])
Chris@87 1984 elif opt[:2] == '-D':
Chris@87 1985 if '=' in opt:
Chris@87 1986 n, v = opt[2:].split('=')
Chris@87 1987 macros.append((n, v))
Chris@87 1988 else:
Chris@87 1989 macros.append((opt[2:], None))
Chris@87 1990 else:
Chris@87 1991 extra_compile_args.append(opt)
Chris@87 1992 if macros:
Chris@87 1993 dict_append(info, define_macros=macros)
Chris@87 1994 if libraries:
Chris@87 1995 dict_append(info, libraries=libraries)
Chris@87 1996 if library_dirs:
Chris@87 1997 dict_append(info, library_dirs=library_dirs)
Chris@87 1998 if include_dirs:
Chris@87 1999 dict_append(info, include_dirs=include_dirs)
Chris@87 2000 if extra_link_args:
Chris@87 2001 dict_append(info, extra_link_args=extra_link_args)
Chris@87 2002 if extra_compile_args:
Chris@87 2003 dict_append(info, extra_compile_args=extra_compile_args)
Chris@87 2004 if info:
Chris@87 2005 self.set_info(**info)
Chris@87 2006 return
Chris@87 2007
Chris@87 2008
Chris@87 2009 class wx_info(_pkg_config_info):
Chris@87 2010 section = 'wx'
Chris@87 2011 config_env_var = 'WX_CONFIG'
Chris@87 2012 default_config_exe = 'wx-config'
Chris@87 2013 append_config_exe = ''
Chris@87 2014 version_macro_name = 'WX_VERSION'
Chris@87 2015 release_macro_name = 'WX_RELEASE'
Chris@87 2016 version_flag = '--version'
Chris@87 2017 cflags_flag = '--cxxflags'
Chris@87 2018
Chris@87 2019
Chris@87 2020 class gdk_pixbuf_xlib_2_info(_pkg_config_info):
Chris@87 2021 section = 'gdk_pixbuf_xlib_2'
Chris@87 2022 append_config_exe = 'gdk-pixbuf-xlib-2.0'
Chris@87 2023 version_macro_name = 'GDK_PIXBUF_XLIB_VERSION'
Chris@87 2024
Chris@87 2025
Chris@87 2026 class gdk_pixbuf_2_info(_pkg_config_info):
Chris@87 2027 section = 'gdk_pixbuf_2'
Chris@87 2028 append_config_exe = 'gdk-pixbuf-2.0'
Chris@87 2029 version_macro_name = 'GDK_PIXBUF_VERSION'
Chris@87 2030
Chris@87 2031
Chris@87 2032 class gdk_x11_2_info(_pkg_config_info):
Chris@87 2033 section = 'gdk_x11_2'
Chris@87 2034 append_config_exe = 'gdk-x11-2.0'
Chris@87 2035 version_macro_name = 'GDK_X11_VERSION'
Chris@87 2036
Chris@87 2037
Chris@87 2038 class gdk_2_info(_pkg_config_info):
Chris@87 2039 section = 'gdk_2'
Chris@87 2040 append_config_exe = 'gdk-2.0'
Chris@87 2041 version_macro_name = 'GDK_VERSION'
Chris@87 2042
Chris@87 2043
Chris@87 2044 class gdk_info(_pkg_config_info):
Chris@87 2045 section = 'gdk'
Chris@87 2046 append_config_exe = 'gdk'
Chris@87 2047 version_macro_name = 'GDK_VERSION'
Chris@87 2048
Chris@87 2049
Chris@87 2050 class gtkp_x11_2_info(_pkg_config_info):
Chris@87 2051 section = 'gtkp_x11_2'
Chris@87 2052 append_config_exe = 'gtk+-x11-2.0'
Chris@87 2053 version_macro_name = 'GTK_X11_VERSION'
Chris@87 2054
Chris@87 2055
Chris@87 2056 class gtkp_2_info(_pkg_config_info):
Chris@87 2057 section = 'gtkp_2'
Chris@87 2058 append_config_exe = 'gtk+-2.0'
Chris@87 2059 version_macro_name = 'GTK_VERSION'
Chris@87 2060
Chris@87 2061
Chris@87 2062 class xft_info(_pkg_config_info):
Chris@87 2063 section = 'xft'
Chris@87 2064 append_config_exe = 'xft'
Chris@87 2065 version_macro_name = 'XFT_VERSION'
Chris@87 2066
Chris@87 2067
Chris@87 2068 class freetype2_info(_pkg_config_info):
Chris@87 2069 section = 'freetype2'
Chris@87 2070 append_config_exe = 'freetype2'
Chris@87 2071 version_macro_name = 'FREETYPE2_VERSION'
Chris@87 2072
Chris@87 2073
Chris@87 2074 class amd_info(system_info):
Chris@87 2075 section = 'amd'
Chris@87 2076 dir_env_var = 'AMD'
Chris@87 2077 _lib_names = ['amd']
Chris@87 2078
Chris@87 2079 def calc_info(self):
Chris@87 2080 lib_dirs = self.get_lib_dirs()
Chris@87 2081
Chris@87 2082 amd_libs = self.get_libs('amd_libs', self._lib_names)
Chris@87 2083 info = self.check_libs(lib_dirs, amd_libs, [])
Chris@87 2084 if info is None:
Chris@87 2085 return
Chris@87 2086
Chris@87 2087 include_dirs = self.get_include_dirs()
Chris@87 2088
Chris@87 2089 inc_dir = None
Chris@87 2090 for d in include_dirs:
Chris@87 2091 p = self.combine_paths(d, 'amd.h')
Chris@87 2092 if p:
Chris@87 2093 inc_dir = os.path.dirname(p[0])
Chris@87 2094 break
Chris@87 2095 if inc_dir is not None:
Chris@87 2096 dict_append(info, include_dirs=[inc_dir],
Chris@87 2097 define_macros=[('SCIPY_AMD_H', None)],
Chris@87 2098 swig_opts=['-I' + inc_dir])
Chris@87 2099
Chris@87 2100 self.set_info(**info)
Chris@87 2101 return
Chris@87 2102
Chris@87 2103
Chris@87 2104 class umfpack_info(system_info):
Chris@87 2105 section = 'umfpack'
Chris@87 2106 dir_env_var = 'UMFPACK'
Chris@87 2107 notfounderror = UmfpackNotFoundError
Chris@87 2108 _lib_names = ['umfpack']
Chris@87 2109
Chris@87 2110 def calc_info(self):
Chris@87 2111 lib_dirs = self.get_lib_dirs()
Chris@87 2112
Chris@87 2113 umfpack_libs = self.get_libs('umfpack_libs', self._lib_names)
Chris@87 2114 info = self.check_libs(lib_dirs, umfpack_libs, [])
Chris@87 2115 if info is None:
Chris@87 2116 return
Chris@87 2117
Chris@87 2118 include_dirs = self.get_include_dirs()
Chris@87 2119
Chris@87 2120 inc_dir = None
Chris@87 2121 for d in include_dirs:
Chris@87 2122 p = self.combine_paths(d, ['', 'umfpack'], 'umfpack.h')
Chris@87 2123 if p:
Chris@87 2124 inc_dir = os.path.dirname(p[0])
Chris@87 2125 break
Chris@87 2126 if inc_dir is not None:
Chris@87 2127 dict_append(info, include_dirs=[inc_dir],
Chris@87 2128 define_macros=[('SCIPY_UMFPACK_H', None)],
Chris@87 2129 swig_opts=['-I' + inc_dir])
Chris@87 2130
Chris@87 2131 amd = get_info('amd')
Chris@87 2132 dict_append(info, **get_info('amd'))
Chris@87 2133
Chris@87 2134 self.set_info(**info)
Chris@87 2135 return
Chris@87 2136
Chris@87 2137 ## def vstr2hex(version):
Chris@87 2138 ## bits = []
Chris@87 2139 ## n = [24,16,8,4,0]
Chris@87 2140 ## r = 0
Chris@87 2141 ## for s in version.split('.'):
Chris@87 2142 ## r |= int(s) << n[0]
Chris@87 2143 ## del n[0]
Chris@87 2144 ## return r
Chris@87 2145
Chris@87 2146 #--------------------------------------------------------------------
Chris@87 2147
Chris@87 2148
Chris@87 2149 def combine_paths(*args, **kws):
Chris@87 2150 """ Return a list of existing paths composed by all combinations of
Chris@87 2151 items from arguments.
Chris@87 2152 """
Chris@87 2153 r = []
Chris@87 2154 for a in args:
Chris@87 2155 if not a:
Chris@87 2156 continue
Chris@87 2157 if is_string(a):
Chris@87 2158 a = [a]
Chris@87 2159 r.append(a)
Chris@87 2160 args = r
Chris@87 2161 if not args:
Chris@87 2162 return []
Chris@87 2163 if len(args) == 1:
Chris@87 2164 result = reduce(lambda a, b: a + b, map(glob, args[0]), [])
Chris@87 2165 elif len(args) == 2:
Chris@87 2166 result = []
Chris@87 2167 for a0 in args[0]:
Chris@87 2168 for a1 in args[1]:
Chris@87 2169 result.extend(glob(os.path.join(a0, a1)))
Chris@87 2170 else:
Chris@87 2171 result = combine_paths(*(combine_paths(args[0], args[1]) + args[2:]))
Chris@87 2172 verbosity = kws.get('verbosity', 1)
Chris@87 2173 log.debug('(paths: %s)', ','.join(result))
Chris@87 2174 return result
Chris@87 2175
Chris@87 2176 language_map = {'c': 0, 'c++': 1, 'f77': 2, 'f90': 3}
Chris@87 2177 inv_language_map = {0: 'c', 1: 'c++', 2: 'f77', 3: 'f90'}
Chris@87 2178
Chris@87 2179
Chris@87 2180 def dict_append(d, **kws):
Chris@87 2181 languages = []
Chris@87 2182 for k, v in kws.items():
Chris@87 2183 if k == 'language':
Chris@87 2184 languages.append(v)
Chris@87 2185 continue
Chris@87 2186 if k in d:
Chris@87 2187 if k in ['library_dirs', 'include_dirs', 'define_macros']:
Chris@87 2188 [d[k].append(vv) for vv in v if vv not in d[k]]
Chris@87 2189 else:
Chris@87 2190 d[k].extend(v)
Chris@87 2191 else:
Chris@87 2192 d[k] = v
Chris@87 2193 if languages:
Chris@87 2194 l = inv_language_map[max([language_map.get(l, 0) for l in languages])]
Chris@87 2195 d['language'] = l
Chris@87 2196 return
Chris@87 2197
Chris@87 2198
Chris@87 2199 def parseCmdLine(argv=(None,)):
Chris@87 2200 import optparse
Chris@87 2201 parser = optparse.OptionParser("usage: %prog [-v] [info objs]")
Chris@87 2202 parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
Chris@87 2203 default=False,
Chris@87 2204 help='be verbose and print more messages')
Chris@87 2205
Chris@87 2206 opts, args = parser.parse_args(args=argv[1:])
Chris@87 2207 return opts, args
Chris@87 2208
Chris@87 2209
Chris@87 2210 def show_all(argv=None):
Chris@87 2211 import inspect
Chris@87 2212 if argv is None:
Chris@87 2213 argv = sys.argv
Chris@87 2214 opts, args = parseCmdLine(argv)
Chris@87 2215 if opts.verbose:
Chris@87 2216 log.set_threshold(log.DEBUG)
Chris@87 2217 else:
Chris@87 2218 log.set_threshold(log.INFO)
Chris@87 2219 show_only = []
Chris@87 2220 for n in args:
Chris@87 2221 if n[-5:] != '_info':
Chris@87 2222 n = n + '_info'
Chris@87 2223 show_only.append(n)
Chris@87 2224 show_all = not show_only
Chris@87 2225 _gdict_ = globals().copy()
Chris@87 2226 for name, c in _gdict_.items():
Chris@87 2227 if not inspect.isclass(c):
Chris@87 2228 continue
Chris@87 2229 if not issubclass(c, system_info) or c is system_info:
Chris@87 2230 continue
Chris@87 2231 if not show_all:
Chris@87 2232 if name not in show_only:
Chris@87 2233 continue
Chris@87 2234 del show_only[show_only.index(name)]
Chris@87 2235 conf = c()
Chris@87 2236 conf.verbosity = 2
Chris@87 2237 r = conf.get_info()
Chris@87 2238 if show_only:
Chris@87 2239 log.info('Info classes not defined: %s', ','.join(show_only))
Chris@87 2240
Chris@87 2241 if __name__ == "__main__":
Chris@87 2242 show_all()