Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/distutils/fcompiler/gnu.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 from __future__ import division, absolute_import, print_function | |
2 | |
3 import re | |
4 import os | |
5 import sys | |
6 import warnings | |
7 import platform | |
8 import tempfile | |
9 from subprocess import Popen, PIPE, STDOUT | |
10 | |
11 from numpy.distutils.cpuinfo import cpu | |
12 from numpy.distutils.fcompiler import FCompiler | |
13 from numpy.distutils.exec_command import exec_command | |
14 from numpy.distutils.misc_util import msvc_runtime_library | |
15 from numpy.distutils.compat import get_exception | |
16 | |
17 compilers = ['GnuFCompiler', 'Gnu95FCompiler'] | |
18 | |
19 TARGET_R = re.compile("Target: ([a-zA-Z0-9_\-]*)") | |
20 | |
21 # XXX: handle cross compilation | |
22 def is_win64(): | |
23 return sys.platform == "win32" and platform.architecture()[0] == "64bit" | |
24 | |
25 if is_win64(): | |
26 #_EXTRAFLAGS = ["-fno-leading-underscore"] | |
27 _EXTRAFLAGS = [] | |
28 else: | |
29 _EXTRAFLAGS = [] | |
30 | |
31 class GnuFCompiler(FCompiler): | |
32 compiler_type = 'gnu' | |
33 compiler_aliases = ('g77',) | |
34 description = 'GNU Fortran 77 compiler' | |
35 | |
36 def gnu_version_match(self, version_string): | |
37 """Handle the different versions of GNU fortran compilers""" | |
38 m = re.search(r'GNU Fortran', version_string) | |
39 if not m: | |
40 return None | |
41 m = re.search(r'GNU Fortran\s+95.*?([0-9-.]+)', version_string) | |
42 if m: | |
43 return ('gfortran', m.group(1)) | |
44 m = re.search(r'GNU Fortran.*?\-?([0-9-.]+)', version_string) | |
45 if m: | |
46 v = m.group(1) | |
47 if v.startswith('0') or v.startswith('2') or v.startswith('3'): | |
48 # the '0' is for early g77's | |
49 return ('g77', v) | |
50 else: | |
51 # at some point in the 4.x series, the ' 95' was dropped | |
52 # from the version string | |
53 return ('gfortran', v) | |
54 | |
55 def version_match(self, version_string): | |
56 v = self.gnu_version_match(version_string) | |
57 if not v or v[0] != 'g77': | |
58 return None | |
59 return v[1] | |
60 | |
61 # 'g77 --version' results | |
62 # SunOS: GNU Fortran (GCC 3.2) 3.2 20020814 (release) | |
63 # Debian: GNU Fortran (GCC) 3.3.3 20040110 (prerelease) (Debian) | |
64 # GNU Fortran (GCC) 3.3.3 (Debian 20040401) | |
65 # GNU Fortran 0.5.25 20010319 (prerelease) | |
66 # Redhat: GNU Fortran (GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) 3.2.2 20030222 (Red Hat Linux 3.2.2-5) | |
67 # GNU Fortran (GCC) 3.4.2 (mingw-special) | |
68 | |
69 possible_executables = ['g77', 'f77'] | |
70 executables = { | |
71 'version_cmd' : [None, "--version"], | |
72 'compiler_f77' : [None, "-g", "-Wall", "-fno-second-underscore"], | |
73 'compiler_f90' : None, # Use --fcompiler=gnu95 for f90 codes | |
74 'compiler_fix' : None, | |
75 'linker_so' : [None, "-g", "-Wall"], | |
76 'archiver' : ["ar", "-cr"], | |
77 'ranlib' : ["ranlib"], | |
78 'linker_exe' : [None, "-g", "-Wall"] | |
79 } | |
80 module_dir_switch = None | |
81 module_include_switch = None | |
82 | |
83 # Cygwin: f771: warning: -fPIC ignored for target (all code is | |
84 # position independent) | |
85 if os.name != 'nt' and sys.platform != 'cygwin': | |
86 pic_flags = ['-fPIC'] | |
87 | |
88 # use -mno-cygwin for g77 when Python is not Cygwin-Python | |
89 if sys.platform == 'win32': | |
90 for key in ['version_cmd', 'compiler_f77', 'linker_so', 'linker_exe']: | |
91 executables[key].append('-mno-cygwin') | |
92 | |
93 g2c = 'g2c' | |
94 | |
95 suggested_f90_compiler = 'gnu95' | |
96 | |
97 #def get_linker_so(self): | |
98 # # win32 linking should be handled by standard linker | |
99 # # Darwin g77 cannot be used as a linker. | |
100 # #if re.match(r'(darwin)', sys.platform): | |
101 # # return | |
102 # return FCompiler.get_linker_so(self) | |
103 | |
104 def get_flags_linker_so(self): | |
105 opt = self.linker_so[1:] | |
106 if sys.platform=='darwin': | |
107 target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', None) | |
108 # If MACOSX_DEPLOYMENT_TARGET is set, we simply trust the value | |
109 # and leave it alone. But, distutils will complain if the | |
110 # environment's value is different from the one in the Python | |
111 # Makefile used to build Python. We let disutils handle this | |
112 # error checking. | |
113 if not target: | |
114 # If MACOSX_DEPLOYMENT_TARGET is not set in the environment, | |
115 # we try to get it first from the Python Makefile and then we | |
116 # fall back to setting it to 10.3 to maximize the set of | |
117 # versions we can work with. This is a reasonable default | |
118 # even when using the official Python dist and those derived | |
119 # from it. | |
120 import distutils.sysconfig as sc | |
121 g = {} | |
122 filename = sc.get_makefile_filename() | |
123 sc.parse_makefile(filename, g) | |
124 target = g.get('MACOSX_DEPLOYMENT_TARGET', '10.3') | |
125 os.environ['MACOSX_DEPLOYMENT_TARGET'] = target | |
126 if target == '10.3': | |
127 s = 'Env. variable MACOSX_DEPLOYMENT_TARGET set to 10.3' | |
128 warnings.warn(s) | |
129 | |
130 opt.extend(['-undefined', 'dynamic_lookup', '-bundle']) | |
131 else: | |
132 opt.append("-shared") | |
133 if sys.platform.startswith('sunos'): | |
134 # SunOS often has dynamically loaded symbols defined in the | |
135 # static library libg2c.a The linker doesn't like this. To | |
136 # ignore the problem, use the -mimpure-text flag. It isn't | |
137 # the safest thing, but seems to work. 'man gcc' says: | |
138 # ".. Instead of using -mimpure-text, you should compile all | |
139 # source code with -fpic or -fPIC." | |
140 opt.append('-mimpure-text') | |
141 return opt | |
142 | |
143 def get_libgcc_dir(self): | |
144 status, output = exec_command(self.compiler_f77 + | |
145 ['-print-libgcc-file-name'], | |
146 use_tee=0) | |
147 if not status: | |
148 return os.path.dirname(output) | |
149 return None | |
150 | |
151 def get_library_dirs(self): | |
152 opt = [] | |
153 if sys.platform[:5] != 'linux': | |
154 d = self.get_libgcc_dir() | |
155 if d: | |
156 # if windows and not cygwin, libg2c lies in a different folder | |
157 if sys.platform == 'win32' and not d.startswith('/usr/lib'): | |
158 d = os.path.normpath(d) | |
159 if not os.path.exists(os.path.join(d, "lib%s.a" % self.g2c)): | |
160 d2 = os.path.abspath(os.path.join(d, | |
161 '../../../../lib')) | |
162 if os.path.exists(os.path.join(d2, "lib%s.a" % self.g2c)): | |
163 opt.append(d2) | |
164 opt.append(d) | |
165 return opt | |
166 | |
167 def get_libraries(self): | |
168 opt = [] | |
169 d = self.get_libgcc_dir() | |
170 if d is not None: | |
171 g2c = self.g2c + '-pic' | |
172 f = self.static_lib_format % (g2c, self.static_lib_extension) | |
173 if not os.path.isfile(os.path.join(d, f)): | |
174 g2c = self.g2c | |
175 else: | |
176 g2c = self.g2c | |
177 | |
178 if g2c is not None: | |
179 opt.append(g2c) | |
180 c_compiler = self.c_compiler | |
181 if sys.platform == 'win32' and c_compiler and \ | |
182 c_compiler.compiler_type=='msvc': | |
183 # the following code is not needed (read: breaks) when using MinGW | |
184 # in case want to link F77 compiled code with MSVC | |
185 opt.append('gcc') | |
186 runtime_lib = msvc_runtime_library() | |
187 if runtime_lib: | |
188 opt.append(runtime_lib) | |
189 if sys.platform == 'darwin': | |
190 opt.append('cc_dynamic') | |
191 return opt | |
192 | |
193 def get_flags_debug(self): | |
194 return ['-g'] | |
195 | |
196 def get_flags_opt(self): | |
197 v = self.get_version() | |
198 if v and v<='3.3.3': | |
199 # With this compiler version building Fortran BLAS/LAPACK | |
200 # with -O3 caused failures in lib.lapack heevr,syevr tests. | |
201 opt = ['-O2'] | |
202 else: | |
203 opt = ['-O3'] | |
204 opt.append('-funroll-loops') | |
205 return opt | |
206 | |
207 def _c_arch_flags(self): | |
208 """ Return detected arch flags from CFLAGS """ | |
209 from distutils import sysconfig | |
210 try: | |
211 cflags = sysconfig.get_config_vars()['CFLAGS'] | |
212 except KeyError: | |
213 return [] | |
214 arch_re = re.compile(r"-arch\s+(\w+)") | |
215 arch_flags = [] | |
216 for arch in arch_re.findall(cflags): | |
217 arch_flags += ['-arch', arch] | |
218 return arch_flags | |
219 | |
220 def get_flags_arch(self): | |
221 return [] | |
222 | |
223 def runtime_library_dir_option(self, dir): | |
224 return '-Wl,-rpath="%s"' % dir | |
225 | |
226 class Gnu95FCompiler(GnuFCompiler): | |
227 compiler_type = 'gnu95' | |
228 compiler_aliases = ('gfortran',) | |
229 description = 'GNU Fortran 95 compiler' | |
230 | |
231 def version_match(self, version_string): | |
232 v = self.gnu_version_match(version_string) | |
233 if not v or v[0] != 'gfortran': | |
234 return None | |
235 v = v[1] | |
236 if v>='4.': | |
237 # gcc-4 series releases do not support -mno-cygwin option | |
238 pass | |
239 else: | |
240 # use -mno-cygwin flag for gfortran when Python is not Cygwin-Python | |
241 if sys.platform == 'win32': | |
242 for key in ['version_cmd', 'compiler_f77', 'compiler_f90', | |
243 'compiler_fix', 'linker_so', 'linker_exe']: | |
244 self.executables[key].append('-mno-cygwin') | |
245 return v | |
246 | |
247 # 'gfortran --version' results: | |
248 # XXX is the below right? | |
249 # Debian: GNU Fortran 95 (GCC 4.0.3 20051023 (prerelease) (Debian 4.0.2-3)) | |
250 # GNU Fortran 95 (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) | |
251 # OS X: GNU Fortran 95 (GCC) 4.1.0 | |
252 # GNU Fortran 95 (GCC) 4.2.0 20060218 (experimental) | |
253 # GNU Fortran (GCC) 4.3.0 20070316 (experimental) | |
254 | |
255 possible_executables = ['gfortran', 'f95'] | |
256 executables = { | |
257 'version_cmd' : ["<F90>", "--version"], | |
258 'compiler_f77' : [None, "-Wall", "-g", "-ffixed-form", | |
259 "-fno-second-underscore"] + _EXTRAFLAGS, | |
260 'compiler_f90' : [None, "-Wall", "-g", | |
261 "-fno-second-underscore"] + _EXTRAFLAGS, | |
262 'compiler_fix' : [None, "-Wall", "-g","-ffixed-form", | |
263 "-fno-second-underscore"] + _EXTRAFLAGS, | |
264 'linker_so' : ["<F90>", "-Wall", "-g"], | |
265 'archiver' : ["ar", "-cr"], | |
266 'ranlib' : ["ranlib"], | |
267 'linker_exe' : [None, "-Wall"] | |
268 } | |
269 | |
270 module_dir_switch = '-J' | |
271 module_include_switch = '-I' | |
272 | |
273 g2c = 'gfortran' | |
274 | |
275 def _universal_flags(self, cmd): | |
276 """Return a list of -arch flags for every supported architecture.""" | |
277 if not sys.platform == 'darwin': | |
278 return [] | |
279 arch_flags = [] | |
280 # get arches the C compiler gets. | |
281 c_archs = self._c_arch_flags() | |
282 if "i386" in c_archs: | |
283 c_archs[c_archs.index("i386")] = "i686" | |
284 # check the arches the Fortran compiler supports, and compare with | |
285 # arch flags from C compiler | |
286 for arch in ["ppc", "i686", "x86_64", "ppc64"]: | |
287 if _can_target(cmd, arch) and arch in c_archs: | |
288 arch_flags.extend(["-arch", arch]) | |
289 return arch_flags | |
290 | |
291 def get_flags(self): | |
292 flags = GnuFCompiler.get_flags(self) | |
293 arch_flags = self._universal_flags(self.compiler_f90) | |
294 if arch_flags: | |
295 flags[:0] = arch_flags | |
296 return flags | |
297 | |
298 def get_flags_linker_so(self): | |
299 flags = GnuFCompiler.get_flags_linker_so(self) | |
300 arch_flags = self._universal_flags(self.linker_so) | |
301 if arch_flags: | |
302 flags[:0] = arch_flags | |
303 return flags | |
304 | |
305 def get_library_dirs(self): | |
306 opt = GnuFCompiler.get_library_dirs(self) | |
307 if sys.platform == 'win32': | |
308 c_compiler = self.c_compiler | |
309 if c_compiler and c_compiler.compiler_type == "msvc": | |
310 target = self.get_target() | |
311 if target: | |
312 d = os.path.normpath(self.get_libgcc_dir()) | |
313 root = os.path.join(d, os.pardir, os.pardir, os.pardir, os.pardir) | |
314 mingwdir = os.path.normpath(os.path.join(root, target, "lib")) | |
315 full = os.path.join(mingwdir, "libmingwex.a") | |
316 if os.path.exists(full): | |
317 opt.append(mingwdir) | |
318 return opt | |
319 | |
320 def get_libraries(self): | |
321 opt = GnuFCompiler.get_libraries(self) | |
322 if sys.platform == 'darwin': | |
323 opt.remove('cc_dynamic') | |
324 if sys.platform == 'win32': | |
325 c_compiler = self.c_compiler | |
326 if c_compiler and c_compiler.compiler_type == "msvc": | |
327 if "gcc" in opt: | |
328 i = opt.index("gcc") | |
329 opt.insert(i+1, "mingwex") | |
330 opt.insert(i+1, "mingw32") | |
331 # XXX: fix this mess, does not work for mingw | |
332 if is_win64(): | |
333 c_compiler = self.c_compiler | |
334 if c_compiler and c_compiler.compiler_type == "msvc": | |
335 return [] | |
336 else: | |
337 raise NotImplementedError("Only MS compiler supported with gfortran on win64") | |
338 return opt | |
339 | |
340 def get_target(self): | |
341 status, output = exec_command(self.compiler_f77 + | |
342 ['-v'], | |
343 use_tee=0) | |
344 if not status: | |
345 m = TARGET_R.search(output) | |
346 if m: | |
347 return m.group(1) | |
348 return "" | |
349 | |
350 def get_flags_opt(self): | |
351 if is_win64(): | |
352 return ['-O0'] | |
353 else: | |
354 return GnuFCompiler.get_flags_opt(self) | |
355 | |
356 def _can_target(cmd, arch): | |
357 """Return true is the command supports the -arch flag for the given | |
358 architecture.""" | |
359 newcmd = cmd[:] | |
360 fid, filename = tempfile.mkstemp(suffix=".f") | |
361 try: | |
362 d = os.path.dirname(filename) | |
363 output = os.path.splitext(filename)[0] + ".o" | |
364 try: | |
365 newcmd.extend(["-arch", arch, "-c", filename]) | |
366 p = Popen(newcmd, stderr=STDOUT, stdout=PIPE, cwd=d) | |
367 p.communicate() | |
368 return p.returncode == 0 | |
369 finally: | |
370 if os.path.exists(output): | |
371 os.remove(output) | |
372 finally: | |
373 os.remove(filename) | |
374 return False | |
375 | |
376 if __name__ == '__main__': | |
377 from distutils import log | |
378 log.set_verbosity(2) | |
379 | |
380 compiler = GnuFCompiler() | |
381 compiler.customize() | |
382 print(compiler.get_version()) | |
383 | |
384 try: | |
385 compiler = Gnu95FCompiler() | |
386 compiler.customize() | |
387 print(compiler.get_version()) | |
388 except Exception: | |
389 msg = get_exception() | |
390 print(msg) |