summaryrefslogtreecommitdiff
path: root/command/config.py
diff options
context:
space:
mode:
Diffstat (limited to 'command/config.py')
-rw-r--r--command/config.py123
1 files changed, 123 insertions, 0 deletions
diff --git a/command/config.py b/command/config.py
new file mode 100644
index 000000000..003f04aad
--- /dev/null
+++ b/command/config.py
@@ -0,0 +1,123 @@
+# Added Fortran compiler support to config. Currently useful only for
+# try_compile call. try_run works but is untested for most of Fortran
+# compilers (they must define linker_exe first).
+# Pearu Peterson
+
+import os, signal
+from distutils.command.config import config as old_config
+from distutils.command.config import LANG_EXT
+from distutils import log
+from numpy.distutils.exec_command import exec_command
+
+LANG_EXT['f77'] = '.f'
+LANG_EXT['f90'] = '.f90'
+
+class config(old_config):
+ old_config.user_options += [
+ ('fcompiler=', None,
+ "specify the Fortran compiler type"),
+ ]
+
+ def initialize_options(self):
+ self.fcompiler = None
+ old_config.initialize_options(self)
+ return
+
+ def finalize_options(self):
+ old_config.finalize_options(self)
+ f = self.distribution.get_command_obj('config_fc')
+ self.set_undefined_options('config_fc',
+ ('fcompiler', 'fcompiler'))
+ return
+
+ def _check_compiler (self):
+ old_config._check_compiler(self)
+ from numpy.distutils.fcompiler import FCompiler, new_fcompiler
+ if not isinstance(self.fcompiler, FCompiler):
+ self.fcompiler = new_fcompiler(compiler=self.fcompiler,
+ dry_run=self.dry_run, force=1)
+ self.fcompiler.customize(self.distribution)
+ self.fcompiler.customize_cmd(self)
+ self.fcompiler.show_customization()
+ return
+
+ def _wrap_method(self,mth,lang,args):
+ from distutils.ccompiler import CompileError
+ from distutils.errors import DistutilsExecError
+ save_compiler = self.compiler
+ if lang in ['f77','f90']:
+ self.compiler = self.fcompiler
+ try:
+ ret = mth(*((self,)+args))
+ except (DistutilsExecError,CompileError),msg:
+ self.compiler = save_compiler
+ raise CompileError
+ self.compiler = save_compiler
+ return ret
+
+ def _compile (self, body, headers, include_dirs, lang):
+ return self._wrap_method(old_config._compile,lang,
+ (body, headers, include_dirs, lang))
+
+ def _link (self, body,
+ headers, include_dirs,
+ libraries, library_dirs, lang):
+ return self._wrap_method(old_config._link,lang,
+ (body, headers, include_dirs,
+ libraries, library_dirs, lang))
+
+ def check_func(self, func,
+ headers=None, include_dirs=None,
+ libraries=None, library_dirs=None,
+ decl=False, call=False, call_args=None):
+ # clean up distutils's config a bit: add void to main(), and
+ # return a value.
+ self._check_compiler()
+ body = []
+ if decl:
+ body.append("int %s ();" % func)
+ body.append("int main (void) {")
+ if call:
+ if call_args is None:
+ call_args = ''
+ body.append(" %s(%s);" % (func, call_args))
+ else:
+ body.append(" %s;" % func)
+ body.append(" return 0;")
+ body.append("}")
+ body = '\n'.join(body) + "\n"
+
+ return self.try_link(body, headers, include_dirs,
+ libraries, library_dirs)
+
+ def get_output(self, body, headers=None, include_dirs=None,
+ libraries=None, library_dirs=None,
+ lang="c"):
+ """Try to compile, link to an executable, and run a program
+ built from 'body' and 'headers'. Returns the exit status code
+ of the program and its output.
+ """
+ from distutils.ccompiler import CompileError, LinkError
+ self._check_compiler()
+ exitcode, output = 255, ''
+ try:
+ src, obj, exe = self._link(body, headers, include_dirs,
+ libraries, library_dirs, lang)
+ exe = os.path.join('.', exe)
+ exitstatus, output = exec_command(exe, execute_in='.')
+ exitcode = os.WEXITSTATUS(exitstatus)
+ if os.WIFSIGNALED(exitstatus):
+ sig = os.WTERMSIG(exitstatus)
+ log.error('subprocess exited with signal %d' % (sig,))
+ if sig == signal.SIGINT:
+ # control-C
+ raise KeyboardInterrupt
+ ok = exitstatus == 0
+ ok = 1
+ except (CompileError, LinkError):
+ ok = 0
+
+ log.info(ok and "success!" or "failure.")
+ self._clean()
+ return exitcode, output
+