system_info.py 88 KB

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