3
# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
5
import re,shutil,os,sys,string,shlex
6
from waflib.Configure import conf
7
from waflib.TaskGen import feature,after_method,before_method
8
from waflib import Build,Utils
9
FC_FRAGMENT=' program main\n end program main\n'
10
FC_FRAGMENT2=' PROGRAM MAIN\n END\n'
14
v['FC_TGT_F']=['-c','-o']
15
v['FCINCPATH_ST']='-I%s'
16
v['FCDEFINES_ST']='-D%s'
17
if not v['LINK_FC']:v['LINK_FC']=v['FC']
19
v['FCLNK_TGT_F']=['-o']
20
v['FCFLAGS_fcshlib']=['-fpic']
21
v['LINKFLAGS_fcshlib']=['-shared']
22
v['fcshlib_PATTERN']='lib%s.so'
23
v['fcstlib_PATTERN']='lib%s.a'
25
v['FCLIBPATH_ST']='-L%s'
26
v['FCSTLIB_ST']='-l%s'
27
v['FCSTLIBPATH_ST']='-L%s'
28
v['FCSTLIB_MARKER']='-Wl,-Bstatic'
29
v['FCSHLIB_MARKER']='-Wl,-Bdynamic'
30
v['SONAME_ST']='-Wl,-h,%s'
31
def check_fortran(self,*k,**kw):
32
self.check_cc(fragment=FC_FRAGMENT,compile_filename='test.f',features='fc fcprogram',msg='Compiling a simple fortran app')
33
def check_fc(self,*k,**kw):
35
if not'compile_mode'in kw:
36
kw['compile_mode']='fc'
38
kw['type']='fcprogram'
39
if not'compile_filename'in kw:
40
kw['compile_filename']='test.f90'
42
kw['code']=FC_FRAGMENT
43
return self.check(*k,**kw)
44
def fortran_modifier_darwin(conf):
46
v['FCFLAGS_fcshlib']=['-fPIC','-compatibility_version','1','-current_version','1']
47
v['LINKFLAGS_fcshlib']=['-dynamiclib']
48
v['fcshlib_PATTERN']='lib%s.dylib'
49
v['FRAMEWORKPATH_ST']='-F%s'
50
v['FRAMEWORK_ST']='-framework %s'
51
v['LINKFLAGS_fcstlib']=[]
52
v['FCSHLIB_MARKER']=''
53
v['FCSTLIB_MARKER']=''
55
def fortran_modifier_win32(conf):
57
v['fcprogram_PATTERN']=v['fcprogram_test_PATTERN']='%s.exe'
58
v['fcshlib_PATTERN']='%s.dll'
59
v['implib_PATTERN']='lib%s.dll.a'
60
v['IMPLIB_ST']='-Wl,--out-implib,%s'
61
v['FCFLAGS_fcshlib']=[]
62
v.append_value('FCFLAGS_fcshlib',['-DDLL_EXPORT'])
63
v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
64
def fortran_modifier_cygwin(conf):
65
fortran_modifier_win32(conf)
67
v['fcshlib_PATTERN']='cyg%s.dll'
68
v.append_value('LINKFLAGS_fcshlib',['-Wl,--enable-auto-image-base'])
69
v['FCFLAGS_fcshlib']=[]
70
def check_fortran_dummy_main(self,*k,**kw):
72
self.fatal('A c compiler is required for check_fortran_dummy_main')
73
lst=['MAIN__','__MAIN','_MAIN','MAIN_','MAIN']
74
lst.extend([m.lower()for m in lst])
76
self.start_msg('Detecting whether we need a dummy main')
78
kw['fortran_main']=main
80
self.check_cc(fragment='int %s() { return 0; }\n'%(main or'test'),features='c fcprogram',mandatory=True)
86
self.end_msg('yes %s'%main)
88
except self.errors.ConfigurationError:
91
self.end_msg('not found')
92
self.fatal('could not detect whether fortran requires a dummy main, see the config.log')
93
GCC_DRIVER_LINE=re.compile('^Driving:')
94
POSIX_STATIC_EXT=re.compile('\S+\.a')
95
POSIX_LIB_FLAGS=re.compile('-l\S+')
96
def is_link_verbose(self,txt):
97
assert isinstance(txt,str)
98
for line in txt.splitlines():
99
if not GCC_DRIVER_LINE.search(line):
100
if POSIX_STATIC_EXT.search(line)or POSIX_LIB_FLAGS.search(line):
103
def check_fortran_verbose_flag(self,*k,**kw):
104
self.start_msg('fortran link verbose flag')
105
for x in['-v','--verbose','-verbose','-V']:
107
self.check_cc(features='fc fcprogram_test',fragment=FC_FRAGMENT2,compile_filename='test.f',linkflags=[x],mandatory=True)
108
except self.errors.ConfigurationError:
111
if self.is_link_verbose(self.test_bld.err)or self.is_link_verbose(self.test_bld.out):
115
self.end_msg('failure')
116
self.fatal('Could not obtain the fortran link verbose flag (see config.log)')
117
self.env.FC_VERBOSE_FLAG=x
119
LINKFLAGS_IGNORED=[r'-lang*',r'-lcrt[a-zA-Z0-9\.]*\.o',r'-lc$',r'-lSystem',r'-libmil',r'-LIST:*',r'-LNO:*']
121
LINKFLAGS_IGNORED.extend([r'-lfrt*',r'-luser32',r'-lkernel32',r'-ladvapi32',r'-lmsvcrt',r'-lshell32',r'-lmingw',r'-lmoldname'])
123
LINKFLAGS_IGNORED.append(r'-lgcc*')
124
RLINKFLAGS_IGNORED=[re.compile(f)for f in LINKFLAGS_IGNORED]
125
def _match_ignore(line):
126
for i in RLINKFLAGS_IGNORED:
130
def parse_fortran_link(lines):
133
if not GCC_DRIVER_LINE.match(line):
134
_parse_flink_line(line,final_flags)
136
SPACE_OPTS=re.compile('^-[LRuYz]$')
137
NOSPACE_OPTS=re.compile('^-[RL]')
138
def _parse_flink_line(line,final_flags):
139
lexer=shlex.shlex(line,posix=True)
140
lexer.whitespace_split=True
145
if _match_ignore(token):
147
elif token.startswith('-lkernel32')and sys.platform=='cygwin':
148
tmp_flags.append(token)
149
elif SPACE_OPTS.match(token):
151
if t.startswith('P,'):
153
for opt in t.split(os.pathsep):
154
tmp_flags.append('-L%s'%opt)
155
elif NOSPACE_OPTS.match(token):
156
tmp_flags.append(token)
157
elif POSIX_LIB_FLAGS.match(token):
158
tmp_flags.append(token)
164
final_flags.extend(tmp_flags)
166
def check_fortran_clib(self,autoadd=True,*k,**kw):
167
if not self.env.FC_VERBOSE_FLAG:
168
self.fatal('env.FC_VERBOSE_FLAG is not set: execute check_fortran_verbose_flag?')
169
self.start_msg('Getting fortran runtime link flags')
171
self.check_cc(fragment=FC_FRAGMENT2,compile_filename='test.f',features='fc fcprogram_test',linkflags=[self.env.FC_VERBOSE_FLAG])
174
if kw.get('mandatory',True):
175
conf.fatal('Could not find the c library flags')
177
out=self.test_bld.err
178
flags=parse_fortran_link(out.splitlines())
179
self.end_msg('ok (%s)'%' '.join(flags))
180
self.env.LINKFLAGS_CLIB=flags
183
def getoutput(conf,cmd,stdin=False):
185
stdin=Utils.subprocess.PIPE
188
env=conf.env.env or None
190
p=Utils.subprocess.Popen(cmd,stdin=stdin,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
193
stdout,stderr=p.communicate()
195
conf.fatal('could not determine the compiler version %r'%cmd)
197
if not isinstance(stdout,str):
198
stdout=stdout.decode(sys.stdout.encoding)
199
if not isinstance(stderr,str):
200
stderr=stderr.decode(sys.stdout.encoding)
211
void %(dummy_func_nounder)s(void);
212
void %(dummy_func_under)s(void);
213
int %(main_func_name)s() {
214
%(dummy_func_nounder)s();
215
%(dummy_func_under)s();
219
def link_main_routines_tg_method(self):
220
def write_test_file(task):
221
task.outputs[0].write(task.generator.code)
223
bld(rule=write_test_file,target='main.c',code=MAIN_CODE%self.__dict__)
224
bld(rule=write_test_file,target='test.f',code=ROUTINES_CODE)
225
bld(features='fc fcstlib',source='test.f',target='test')
226
bld(features='c fcprogram',source='main.c',target='app',use='test')
227
def mangling_schemes():
230
for c in["lower","upper"]:
232
def mangle_name(u,du,c,name):
233
return getattr(name,c)()+u+(name.find('_')!=-1 and du or'')
234
def check_fortran_mangling(self,*k,**kw):
236
self.fatal('A c compiler is required for link_main_routines')
238
self.fatal('A fortran compiler is required for link_main_routines')
239
if not self.env.FC_MAIN:
240
self.fatal('Checking for mangling requires self.env.FC_MAIN (execute "check_fortran_dummy_main" first?)')
241
self.start_msg('Getting fortran mangling scheme')
242
for(u,du,c)in mangling_schemes():
244
self.check_cc(compile_filename=[],features='link_main_routines_func',msg='nomsg',errmsg='nomsg',mandatory=True,dummy_func_nounder=mangle_name(u,du,c,"foobar"),dummy_func_under=mangle_name(u,du,c,"foo_bar"),main_func_name=self.env.FC_MAIN)
245
except self.errors.ConfigurationError:
248
self.end_msg("ok ('%s', '%s', '%s-case')"%(u,du,c))
249
self.env.FORTRAN_MANGLING=(u,du,c)
253
self.fatal('mangler not found')
255
def set_lib_pat(self):
256
self.env['fcshlib_PATTERN']=self.env['pyext_PATTERN']
257
def detect_openmp(self):
258
for x in['-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp']:
260
self.check_fc(msg='Checking for OpenMP flag %s'%x,fragment='program main\n call omp_get_num_threads()\nend program main',fcflags=x,linkflags=x,uselib_store='OPENMP')
261
except self.errors.ConfigurationError:
266
self.fatal('Could not find OpenMP')
271
conf(fortran_modifier_darwin)
272
conf(fortran_modifier_win32)
273
conf(fortran_modifier_cygwin)
274
conf(check_fortran_dummy_main)
275
conf(is_link_verbose)
276
conf(check_fortran_verbose_flag)
277
conf(check_fortran_clib)
278
feature('link_main_routines_func')(link_main_routines_tg_method)
279
before_method('process_source')(link_main_routines_tg_method)
280
conf(check_fortran_mangling)
281
feature('pyext')(set_lib_pat)
282
before_method('propagate_uselib_vars','apply_link')(set_lib_pat)
b'\\ No newline at end of file'