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