f2py2e.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. #!/usr/bin/env python
  2. """
  3. f2py2e - Fortran to Python C/API generator. 2nd Edition.
  4. See __usage__ below.
  5. Copyright 1999--2011 Pearu Peterson all rights reserved,
  6. Pearu Peterson <pearu@cens.ioc.ee>
  7. Permission to use, modify, and distribute this software is given under the
  8. terms of the NumPy License.
  9. NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
  10. $Date: 2005/05/06 08:31:19 $
  11. Pearu Peterson
  12. """
  13. from __future__ import division, absolute_import, print_function
  14. import sys
  15. import os
  16. import pprint
  17. import re
  18. from . import crackfortran
  19. from . import rules
  20. from . import cb_rules
  21. from . import auxfuncs
  22. from . import cfuncs
  23. from . import f90mod_rules
  24. from . import __version__
  25. f2py_version = __version__.version
  26. errmess = sys.stderr.write
  27. # outmess=sys.stdout.write
  28. show = pprint.pprint
  29. outmess = auxfuncs.outmess
  30. try:
  31. from numpy import __version__ as numpy_version
  32. except ImportError:
  33. numpy_version = 'N/A'
  34. __usage__ = """\
  35. Usage:
  36. 1) To construct extension module sources:
  37. f2py [<options>] <fortran files> [[[only:]||[skip:]] \\
  38. <fortran functions> ] \\
  39. [: <fortran files> ...]
  40. 2) To compile fortran files and build extension modules:
  41. f2py -c [<options>, <build_flib options>, <extra options>] <fortran files>
  42. 3) To generate signature files:
  43. f2py -h <filename.pyf> ...< same options as in (1) >
  44. Description: This program generates a Python C/API file (<modulename>module.c)
  45. that contains wrappers for given fortran functions so that they
  46. can be called from Python. With the -c option the corresponding
  47. extension modules are built.
  48. Options:
  49. --2d-numpy Use numpy.f2py tool with NumPy support. [DEFAULT]
  50. --2d-numeric Use f2py2e tool with Numeric support.
  51. --2d-numarray Use f2py2e tool with Numarray support.
  52. --g3-numpy Use 3rd generation f2py from the separate f2py package.
  53. [NOT AVAILABLE YET]
  54. -h <filename> Write signatures of the fortran routines to file <filename>
  55. and exit. You can then edit <filename> and use it instead
  56. of <fortran files>. If <filename>==stdout then the
  57. signatures are printed to stdout.
  58. <fortran functions> Names of fortran routines for which Python C/API
  59. functions will be generated. Default is all that are found
  60. in <fortran files>.
  61. <fortran files> Paths to fortran/signature files that will be scanned for
  62. <fortran functions> in order to determine their signatures.
  63. skip: Ignore fortran functions that follow until `:'.
  64. only: Use only fortran functions that follow until `:'.
  65. : Get back to <fortran files> mode.
  66. -m <modulename> Name of the module; f2py generates a Python/C API
  67. file <modulename>module.c or extension module <modulename>.
  68. Default is 'untitled'.
  69. --[no-]lower Do [not] lower the cases in <fortran files>. By default,
  70. --lower is assumed with -h key, and --no-lower without -h key.
  71. --build-dir <dirname> All f2py generated files are created in <dirname>.
  72. Default is tempfile.mkdtemp().
  73. --overwrite-signature Overwrite existing signature file.
  74. --[no-]latex-doc Create (or not) <modulename>module.tex.
  75. Default is --no-latex-doc.
  76. --short-latex Create 'incomplete' LaTeX document (without commands
  77. \\documentclass, \\tableofcontents, and \\begin{document},
  78. \\end{document}).
  79. --[no-]rest-doc Create (or not) <modulename>module.rst.
  80. Default is --no-rest-doc.
  81. --debug-capi Create C/API code that reports the state of the wrappers
  82. during runtime. Useful for debugging.
  83. --[no-]wrap-functions Create Fortran subroutine wrappers to Fortran 77
  84. functions. --wrap-functions is default because it ensures
  85. maximum portability/compiler independence.
  86. --include-paths <path1>:<path2>:... Search include files from the given
  87. directories.
  88. --help-link [..] List system resources found by system_info.py. See also
  89. --link-<resource> switch below. [..] is optional list
  90. of resources names. E.g. try 'f2py --help-link lapack_opt'.
  91. --quiet Run quietly.
  92. --verbose Run with extra verbosity.
  93. -v Print f2py version ID and exit.
  94. numpy.distutils options (only effective with -c):
  95. --fcompiler= Specify Fortran compiler type by vendor
  96. --compiler= Specify C compiler type (as defined by distutils)
  97. --help-fcompiler List available Fortran compilers and exit
  98. --f77exec= Specify the path to F77 compiler
  99. --f90exec= Specify the path to F90 compiler
  100. --f77flags= Specify F77 compiler flags
  101. --f90flags= Specify F90 compiler flags
  102. --opt= Specify optimization flags
  103. --arch= Specify architecture specific optimization flags
  104. --noopt Compile without optimization
  105. --noarch Compile without arch-dependent optimization
  106. --debug Compile with debugging information
  107. Extra options (only effective with -c):
  108. --link-<resource> Link extension module with <resource> as defined
  109. by numpy.distutils/system_info.py. E.g. to link
  110. with optimized LAPACK libraries (vecLib on MacOSX,
  111. ATLAS elsewhere), use --link-lapack_opt.
  112. See also --help-link switch.
  113. -L/path/to/lib/ -l<libname>
  114. -D<define> -U<name>
  115. -I/path/to/include/
  116. <filename>.o <filename>.so <filename>.a
  117. Using the following macros may be required with non-gcc Fortran
  118. compilers:
  119. -DPREPEND_FORTRAN -DNO_APPEND_FORTRAN -DUPPERCASE_FORTRAN
  120. -DUNDERSCORE_G77
  121. When using -DF2PY_REPORT_ATEXIT, a performance report of F2PY
  122. interface is printed out at exit (platforms: Linux).
  123. When using -DF2PY_REPORT_ON_ARRAY_COPY=<int>, a message is
  124. sent to stderr whenever F2PY interface makes a copy of an
  125. array. Integer <int> sets the threshold for array sizes when
  126. a message should be shown.
  127. Version: %s
  128. numpy Version: %s
  129. Requires: Python 2.3 or higher.
  130. License: NumPy license (see LICENSE.txt in the NumPy source code)
  131. Copyright 1999 - 2011 Pearu Peterson all rights reserved.
  132. http://cens.ioc.ee/projects/f2py2e/""" % (f2py_version, numpy_version)
  133. def scaninputline(inputline):
  134. files, skipfuncs, onlyfuncs, debug = [], [], [], []
  135. f, f2, f3, f5, f6, f7, f8, f9 = 1, 0, 0, 0, 0, 0, 0, 0
  136. verbose = 1
  137. dolc = -1
  138. dolatexdoc = 0
  139. dorestdoc = 0
  140. wrapfuncs = 1
  141. buildpath = '.'
  142. include_paths = []
  143. signsfile, modulename = None, None
  144. options = {'buildpath': buildpath,
  145. 'coutput': None,
  146. 'f2py_wrapper_output': None}
  147. for l in inputline:
  148. if l == '':
  149. pass
  150. elif l == 'only:':
  151. f = 0
  152. elif l == 'skip:':
  153. f = -1
  154. elif l == ':':
  155. f = 1
  156. elif l[:8] == '--debug-':
  157. debug.append(l[8:])
  158. elif l == '--lower':
  159. dolc = 1
  160. elif l == '--build-dir':
  161. f6 = 1
  162. elif l == '--no-lower':
  163. dolc = 0
  164. elif l == '--quiet':
  165. verbose = 0
  166. elif l == '--verbose':
  167. verbose += 1
  168. elif l == '--latex-doc':
  169. dolatexdoc = 1
  170. elif l == '--no-latex-doc':
  171. dolatexdoc = 0
  172. elif l == '--rest-doc':
  173. dorestdoc = 1
  174. elif l == '--no-rest-doc':
  175. dorestdoc = 0
  176. elif l == '--wrap-functions':
  177. wrapfuncs = 1
  178. elif l == '--no-wrap-functions':
  179. wrapfuncs = 0
  180. elif l == '--short-latex':
  181. options['shortlatex'] = 1
  182. elif l == '--coutput':
  183. f8 = 1
  184. elif l == '--f2py-wrapper-output':
  185. f9 = 1
  186. elif l == '--overwrite-signature':
  187. options['h-overwrite'] = 1
  188. elif l == '-h':
  189. f2 = 1
  190. elif l == '-m':
  191. f3 = 1
  192. elif l[:2] == '-v':
  193. print(f2py_version)
  194. sys.exit()
  195. elif l == '--show-compilers':
  196. f5 = 1
  197. elif l[:8] == '-include':
  198. cfuncs.outneeds['userincludes'].append(l[9:-1])
  199. cfuncs.userincludes[l[9:-1]] = '#include ' + l[8:]
  200. elif l[:15] in '--include_paths':
  201. outmess(
  202. 'f2py option --include_paths is deprecated, use --include-paths instead.\n')
  203. f7 = 1
  204. elif l[:15] in '--include-paths':
  205. f7 = 1
  206. elif l[0] == '-':
  207. errmess('Unknown option %s\n' % repr(l))
  208. sys.exit()
  209. elif f2:
  210. f2 = 0
  211. signsfile = l
  212. elif f3:
  213. f3 = 0
  214. modulename = l
  215. elif f6:
  216. f6 = 0
  217. buildpath = l
  218. elif f7:
  219. f7 = 0
  220. include_paths.extend(l.split(os.pathsep))
  221. elif f8:
  222. f8 = 0
  223. options["coutput"] = l
  224. elif f9:
  225. f9 = 0
  226. options["f2py_wrapper_output"] = l
  227. elif f == 1:
  228. try:
  229. open(l).close()
  230. files.append(l)
  231. except IOError as detail:
  232. errmess('IOError: %s. Skipping file "%s".\n' %
  233. (str(detail), l))
  234. elif f == -1:
  235. skipfuncs.append(l)
  236. elif f == 0:
  237. onlyfuncs.append(l)
  238. if not f5 and not files and not modulename:
  239. print(__usage__)
  240. sys.exit()
  241. if not os.path.isdir(buildpath):
  242. if not verbose:
  243. outmess('Creating build directory %s' % (buildpath))
  244. os.mkdir(buildpath)
  245. if signsfile:
  246. signsfile = os.path.join(buildpath, signsfile)
  247. if signsfile and os.path.isfile(signsfile) and 'h-overwrite' not in options:
  248. errmess(
  249. 'Signature file "%s" exists!!! Use --overwrite-signature to overwrite.\n' % (signsfile))
  250. sys.exit()
  251. options['debug'] = debug
  252. options['verbose'] = verbose
  253. if dolc == -1 and not signsfile:
  254. options['do-lower'] = 0
  255. else:
  256. options['do-lower'] = dolc
  257. if modulename:
  258. options['module'] = modulename
  259. if signsfile:
  260. options['signsfile'] = signsfile
  261. if onlyfuncs:
  262. options['onlyfuncs'] = onlyfuncs
  263. if skipfuncs:
  264. options['skipfuncs'] = skipfuncs
  265. options['dolatexdoc'] = dolatexdoc
  266. options['dorestdoc'] = dorestdoc
  267. options['wrapfuncs'] = wrapfuncs
  268. options['buildpath'] = buildpath
  269. options['include_paths'] = include_paths
  270. return files, options
  271. def callcrackfortran(files, options):
  272. rules.options = options
  273. crackfortran.debug = options['debug']
  274. crackfortran.verbose = options['verbose']
  275. if 'module' in options:
  276. crackfortran.f77modulename = options['module']
  277. if 'skipfuncs' in options:
  278. crackfortran.skipfuncs = options['skipfuncs']
  279. if 'onlyfuncs' in options:
  280. crackfortran.onlyfuncs = options['onlyfuncs']
  281. crackfortran.include_paths[:] = options['include_paths']
  282. crackfortran.dolowercase = options['do-lower']
  283. postlist = crackfortran.crackfortran(files)
  284. if 'signsfile' in options:
  285. outmess('Saving signatures to file "%s"\n' % (options['signsfile']))
  286. pyf = crackfortran.crack2fortran(postlist)
  287. if options['signsfile'][-6:] == 'stdout':
  288. sys.stdout.write(pyf)
  289. else:
  290. f = open(options['signsfile'], 'w')
  291. f.write(pyf)
  292. f.close()
  293. if options["coutput"] is None:
  294. for mod in postlist:
  295. mod["coutput"] = "%smodule.c" % mod["name"]
  296. else:
  297. for mod in postlist:
  298. mod["coutput"] = options["coutput"]
  299. if options["f2py_wrapper_output"] is None:
  300. for mod in postlist:
  301. mod["f2py_wrapper_output"] = "%s-f2pywrappers.f" % mod["name"]
  302. else:
  303. for mod in postlist:
  304. mod["f2py_wrapper_output"] = options["f2py_wrapper_output"]
  305. return postlist
  306. def buildmodules(lst):
  307. cfuncs.buildcfuncs()
  308. outmess('Building modules...\n')
  309. modules, mnames, isusedby = [], [], {}
  310. for i in range(len(lst)):
  311. if '__user__' in lst[i]['name']:
  312. cb_rules.buildcallbacks(lst[i])
  313. else:
  314. if 'use' in lst[i]:
  315. for u in lst[i]['use'].keys():
  316. if u not in isusedby:
  317. isusedby[u] = []
  318. isusedby[u].append(lst[i]['name'])
  319. modules.append(lst[i])
  320. mnames.append(lst[i]['name'])
  321. ret = {}
  322. for i in range(len(mnames)):
  323. if mnames[i] in isusedby:
  324. outmess('\tSkipping module "%s" which is used by %s.\n' % (
  325. mnames[i], ','.join(['"%s"' % s for s in isusedby[mnames[i]]])))
  326. else:
  327. um = []
  328. if 'use' in modules[i]:
  329. for u in modules[i]['use'].keys():
  330. if u in isusedby and u in mnames:
  331. um.append(modules[mnames.index(u)])
  332. else:
  333. outmess(
  334. '\tModule "%s" uses nonexisting "%s" which will be ignored.\n' % (mnames[i], u))
  335. ret[mnames[i]] = {}
  336. dict_append(ret[mnames[i]], rules.buildmodule(modules[i], um))
  337. return ret
  338. def dict_append(d_out, d_in):
  339. for (k, v) in d_in.items():
  340. if k not in d_out:
  341. d_out[k] = []
  342. if isinstance(v, list):
  343. d_out[k] = d_out[k] + v
  344. else:
  345. d_out[k].append(v)
  346. def run_main(comline_list):
  347. """
  348. Equivalent to running::
  349. f2py <args>
  350. where ``<args>=string.join(<list>,' ')``, but in Python. Unless
  351. ``-h`` is used, this function returns a dictionary containing
  352. information on generated modules and their dependencies on source
  353. files. For example, the command ``f2py -m scalar scalar.f`` can be
  354. executed from Python as follows
  355. You cannot build extension modules with this function, that is,
  356. using ``-c`` is not allowed. Use ``compile`` command instead
  357. Examples
  358. --------
  359. .. include:: run_main_session.dat
  360. :literal:
  361. """
  362. crackfortran.reset_global_f2py_vars()
  363. f2pydir = os.path.dirname(os.path.abspath(cfuncs.__file__))
  364. fobjhsrc = os.path.join(f2pydir, 'src', 'fortranobject.h')
  365. fobjcsrc = os.path.join(f2pydir, 'src', 'fortranobject.c')
  366. files, options = scaninputline(comline_list)
  367. auxfuncs.options = options
  368. postlist = callcrackfortran(files, options)
  369. isusedby = {}
  370. for i in range(len(postlist)):
  371. if 'use' in postlist[i]:
  372. for u in postlist[i]['use'].keys():
  373. if u not in isusedby:
  374. isusedby[u] = []
  375. isusedby[u].append(postlist[i]['name'])
  376. for i in range(len(postlist)):
  377. if postlist[i]['block'] == 'python module' and '__user__' in postlist[i]['name']:
  378. if postlist[i]['name'] in isusedby:
  379. # if not quiet:
  380. outmess('Skipping Makefile build for module "%s" which is used by %s\n' % (
  381. postlist[i]['name'], ','.join(['"%s"' % s for s in isusedby[postlist[i]['name']]])))
  382. if 'signsfile' in options:
  383. if options['verbose'] > 1:
  384. outmess(
  385. 'Stopping. Edit the signature file and then run f2py on the signature file: ')
  386. outmess('%s %s\n' %
  387. (os.path.basename(sys.argv[0]), options['signsfile']))
  388. return
  389. for i in range(len(postlist)):
  390. if postlist[i]['block'] != 'python module':
  391. if 'python module' not in options:
  392. errmess(
  393. 'Tip: If your original code is Fortran source then you must use -m option.\n')
  394. raise TypeError('All blocks must be python module blocks but got %s' % (
  395. repr(postlist[i]['block'])))
  396. auxfuncs.debugoptions = options['debug']
  397. f90mod_rules.options = options
  398. auxfuncs.wrapfuncs = options['wrapfuncs']
  399. ret = buildmodules(postlist)
  400. for mn in ret.keys():
  401. dict_append(ret[mn], {'csrc': fobjcsrc, 'h': fobjhsrc})
  402. return ret
  403. def filter_files(prefix, suffix, files, remove_prefix=None):
  404. """
  405. Filter files by prefix and suffix.
  406. """
  407. filtered, rest = [], []
  408. match = re.compile(prefix + r'.*' + suffix + r'\Z').match
  409. if remove_prefix:
  410. ind = len(prefix)
  411. else:
  412. ind = 0
  413. for file in [x.strip() for x in files]:
  414. if match(file):
  415. filtered.append(file[ind:])
  416. else:
  417. rest.append(file)
  418. return filtered, rest
  419. def get_prefix(module):
  420. p = os.path.dirname(os.path.dirname(module.__file__))
  421. return p
  422. def run_compile():
  423. """
  424. Do it all in one call!
  425. """
  426. import tempfile
  427. i = sys.argv.index('-c')
  428. del sys.argv[i]
  429. remove_build_dir = 0
  430. try:
  431. i = sys.argv.index('--build-dir')
  432. except ValueError:
  433. i = None
  434. if i is not None:
  435. build_dir = sys.argv[i + 1]
  436. del sys.argv[i + 1]
  437. del sys.argv[i]
  438. else:
  439. remove_build_dir = 1
  440. build_dir = tempfile.mkdtemp()
  441. _reg1 = re.compile(r'[-][-]link[-]')
  442. sysinfo_flags = [_m for _m in sys.argv[1:] if _reg1.match(_m)]
  443. sys.argv = [_m for _m in sys.argv if _m not in sysinfo_flags]
  444. if sysinfo_flags:
  445. sysinfo_flags = [f[7:] for f in sysinfo_flags]
  446. _reg2 = re.compile(
  447. r'[-][-]((no[-]|)(wrap[-]functions|lower)|debug[-]capi|quiet)|[-]include')
  448. f2py_flags = [_m for _m in sys.argv[1:] if _reg2.match(_m)]
  449. sys.argv = [_m for _m in sys.argv if _m not in f2py_flags]
  450. f2py_flags2 = []
  451. fl = 0
  452. for a in sys.argv[1:]:
  453. if a in ['only:', 'skip:']:
  454. fl = 1
  455. elif a == ':':
  456. fl = 0
  457. if fl or a == ':':
  458. f2py_flags2.append(a)
  459. if f2py_flags2 and f2py_flags2[-1] != ':':
  460. f2py_flags2.append(':')
  461. f2py_flags.extend(f2py_flags2)
  462. sys.argv = [_m for _m in sys.argv if _m not in f2py_flags2]
  463. _reg3 = re.compile(
  464. r'[-][-]((f(90)?compiler([-]exec|)|compiler)=|help[-]compiler)')
  465. flib_flags = [_m for _m in sys.argv[1:] if _reg3.match(_m)]
  466. sys.argv = [_m for _m in sys.argv if _m not in flib_flags]
  467. _reg4 = re.compile(
  468. r'[-][-]((f(77|90)(flags|exec)|opt|arch)=|(debug|noopt|noarch|help[-]fcompiler))')
  469. fc_flags = [_m for _m in sys.argv[1:] if _reg4.match(_m)]
  470. sys.argv = [_m for _m in sys.argv if _m not in fc_flags]
  471. if 1:
  472. del_list = []
  473. for s in flib_flags:
  474. v = '--fcompiler='
  475. if s[:len(v)] == v:
  476. from numpy.distutils import fcompiler
  477. fcompiler.load_all_fcompiler_classes()
  478. allowed_keys = list(fcompiler.fcompiler_class.keys())
  479. nv = ov = s[len(v):].lower()
  480. if ov not in allowed_keys:
  481. vmap = {} # XXX
  482. try:
  483. nv = vmap[ov]
  484. except KeyError:
  485. if ov not in vmap.values():
  486. print('Unknown vendor: "%s"' % (s[len(v):]))
  487. nv = ov
  488. i = flib_flags.index(s)
  489. flib_flags[i] = '--fcompiler=' + nv
  490. continue
  491. for s in del_list:
  492. i = flib_flags.index(s)
  493. del flib_flags[i]
  494. assert len(flib_flags) <= 2, repr(flib_flags)
  495. _reg5 = re.compile(r'[-][-](verbose)')
  496. setup_flags = [_m for _m in sys.argv[1:] if _reg5.match(_m)]
  497. sys.argv = [_m for _m in sys.argv if _m not in setup_flags]
  498. if '--quiet' in f2py_flags:
  499. setup_flags.append('--quiet')
  500. modulename = 'untitled'
  501. sources = sys.argv[1:]
  502. for optname in ['--include_paths', '--include-paths']:
  503. if optname in sys.argv:
  504. i = sys.argv.index(optname)
  505. f2py_flags.extend(sys.argv[i:i + 2])
  506. del sys.argv[i + 1], sys.argv[i]
  507. sources = sys.argv[1:]
  508. if '-m' in sys.argv:
  509. i = sys.argv.index('-m')
  510. modulename = sys.argv[i + 1]
  511. del sys.argv[i + 1], sys.argv[i]
  512. sources = sys.argv[1:]
  513. else:
  514. from numpy.distutils.command.build_src import get_f2py_modulename
  515. pyf_files, sources = filter_files('', '[.]pyf([.]src|)', sources)
  516. sources = pyf_files + sources
  517. for f in pyf_files:
  518. modulename = get_f2py_modulename(f)
  519. if modulename:
  520. break
  521. extra_objects, sources = filter_files('', '[.](o|a|so)', sources)
  522. include_dirs, sources = filter_files('-I', '', sources, remove_prefix=1)
  523. library_dirs, sources = filter_files('-L', '', sources, remove_prefix=1)
  524. libraries, sources = filter_files('-l', '', sources, remove_prefix=1)
  525. undef_macros, sources = filter_files('-U', '', sources, remove_prefix=1)
  526. define_macros, sources = filter_files('-D', '', sources, remove_prefix=1)
  527. for i in range(len(define_macros)):
  528. name_value = define_macros[i].split('=', 1)
  529. if len(name_value) == 1:
  530. name_value.append(None)
  531. if len(name_value) == 2:
  532. define_macros[i] = tuple(name_value)
  533. else:
  534. print('Invalid use of -D:', name_value)
  535. from numpy.distutils.system_info import get_info
  536. num_info = {}
  537. if num_info:
  538. include_dirs.extend(num_info.get('include_dirs', []))
  539. from numpy.distutils.core import setup, Extension
  540. ext_args = {'name': modulename, 'sources': sources,
  541. 'include_dirs': include_dirs,
  542. 'library_dirs': library_dirs,
  543. 'libraries': libraries,
  544. 'define_macros': define_macros,
  545. 'undef_macros': undef_macros,
  546. 'extra_objects': extra_objects,
  547. 'f2py_options': f2py_flags,
  548. }
  549. if sysinfo_flags:
  550. from numpy.distutils.misc_util import dict_append
  551. for n in sysinfo_flags:
  552. i = get_info(n)
  553. if not i:
  554. outmess('No %s resources found in system'
  555. ' (try `f2py --help-link`)\n' % (repr(n)))
  556. dict_append(ext_args, **i)
  557. ext = Extension(**ext_args)
  558. sys.argv = [sys.argv[0]] + setup_flags
  559. sys.argv.extend(['build',
  560. '--build-temp', build_dir,
  561. '--build-base', build_dir,
  562. '--build-platlib', '.'])
  563. if fc_flags:
  564. sys.argv.extend(['config_fc'] + fc_flags)
  565. if flib_flags:
  566. sys.argv.extend(['build_ext'] + flib_flags)
  567. setup(ext_modules=[ext])
  568. if remove_build_dir and os.path.exists(build_dir):
  569. import shutil
  570. outmess('Removing build directory %s\n' % (build_dir))
  571. shutil.rmtree(build_dir)
  572. def main():
  573. if '--help-link' in sys.argv[1:]:
  574. sys.argv.remove('--help-link')
  575. from numpy.distutils.system_info import show_all
  576. show_all()
  577. return
  578. # Probably outdated options that were not working before 1.16
  579. if '--g3-numpy' in sys.argv[1:]:
  580. sys.stderr.write("G3 f2py support is not implemented, yet.\\n")
  581. sys.exit(1)
  582. elif '--2e-numeric' in sys.argv[1:]:
  583. sys.argv.remove('--2e-numeric')
  584. elif '--2e-numarray' in sys.argv[1:]:
  585. # Note that this errors becaust the -DNUMARRAY argument is
  586. # not recognized. Just here for back compatibility and the
  587. # error message.
  588. sys.argv.append("-DNUMARRAY")
  589. sys.argv.remove('--2e-numarray')
  590. elif '--2e-numpy' in sys.argv[1:]:
  591. sys.argv.remove('--2e-numpy')
  592. else:
  593. pass
  594. if '-c' in sys.argv[1:]:
  595. run_compile()
  596. else:
  597. run_main(sys.argv[1:])