comparison DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/f2py/f2py2e.py @ 87:2a2c65a20a8b

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