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()
|