def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so = self.compiler_so if sys.platform == 'darwin': compiler_so = _osx_support.compiler_fixup(compiler_so, cc_args + extra_postargs) try: self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg)
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so = self.compiler_so if ext == ".f90": if sys.platform == 'darwin' or sys.platform == 'linux2': compiler_so = ["gfortran"] cc_args = ["-O", "-fPIC", "-c", "-ffree-form"] try: self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError(msg): raise CompileError(msg)
def compile_cxxfile(module_name, cxxfile, output_binary=None, **kwargs): '''c++ file -> native module Return the filename of the produced shared library Raises CompileError on failure ''' builddir = mkdtemp() buildtmp = mkdtemp() extension_args = make_extension(python=True, **kwargs) extension = PythranExtension(module_name, [cxxfile], **extension_args) try: setup( name=module_name, ext_modules=[extension], cmdclass={"build_ext": PythranBuildExt}, # fake CLI call script_name='setup.py', script_args=[ '--verbose' if logger.isEnabledFor(logging.INFO) else '--quiet', 'build_ext', '--build-lib', builddir, '--build-temp', buildtmp ]) except SystemExit as e: raise CompileError(str(e)) def copy(src_file, dest_file): # not using shutil.copy because it fails to copy stat across devices with open(src_file, 'rb') as src: with open(dest_file, 'wb') as dest: dest.write(src.read()) ext = sysconfig.get_config_var('SO') # Copy all generated files including the module name prefix (.pdb, ...) for f in glob.glob(os.path.join(builddir, module_name + "*")): if f.endswith(ext): if not output_binary: output_binary = os.path.join(os.getcwd(), module_name + ext) copy(f, output_binary) else: if not output_binary: output_directory = os.getcwd() else: output_directory = os.path.dirname(output_binary) copy(f, os.path.join(output_directory, os.path.basename(f))) shutil.rmtree(builddir) shutil.rmtree(buildtmp) logger.info("Generated module: " + module_name) logger.info("Output: " + output_binary) return output_binary
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): if cc.__name__ == "UnixCCompiler": compiler_so = self.fixup_compiler(self.compiler_so, cc_args + extra_postargs) try: self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg) else: cc._compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts)
def run(self): if not self.extensions: return version = get_rust_version() if version not in MIN_VERSION: print('Rust version mismatch: required rust%s got rust%s' % (MIN_VERSION, version)) return # Make sure that if pythonXX-sys is used, it builds against the current # executing python interpreter. bindir = os.path.dirname(sys.executable) env = os.environ.copy() env.update({ # disables rust's pkg-config seeking for specified packages, # which causes pythonXX-sys to fall back to detecting the # interpreter from the path. "PYTHON_2.7_NO_PKG_CONFIG": "1", "PATH": bindir + os.pathsep + os.environ.get("PATH", "") }) for ext in self.extensions: if not os.path.exists(ext.path): raise DistutilsFileError( "Can not file rust extension project file: %s" % ext.path) features = set(ext.features) features.update( cpython_feature(ext=False, pyo3=ext.pyo3, no_binding=ext.no_binding)) # build cargo command args = ([ "cargo", "test", '--color', 'always', "--manifest-path", ext.path, "--features", " ".join(features) ] + list(ext.args or [])) # Execute cargo command print(' '.join(args)) try: subprocess.check_output(args) except subprocess.CalledProcessError as e: raise CompileError("cargo failed with code: %d\n%s" % (e.returncode, e.output.decode("utf-8"))) except OSError: raise DistutilsExecError( "Unable to execute 'cargo' - this package " "requires rust to be installed and " "cargo to be on the PATH") else: print("Test has been completed for '%s' extension" % ext.name)
def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): """Compile a single source files with a Unix-style compiler.""" display = '%s: %s' % (os.path.basename(self.compiler_so[0]), src) try: self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + extra_postargs, display=display) except DistutilsExecError: msg = str(get_exception()) raise CompileError(msg)
def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): """Compile a single source files with a Unix-style compiler.""" # HP ad-hoc fix, see ticket 1383 ccomp = self.compiler_so if ccomp[0] == 'aCC': # remove flags that will trigger ANSI-C mode for aCC if '-Ae' in ccomp: ccomp.remove('-Ae') if '-Aa' in ccomp: ccomp.remove('-Aa') # add flags for (almost) sane C++ handling ccomp += ['-AA'] self.compiler_so = ccomp # ensure OPT environment variable is read if 'OPT' in os.environ: # XXX who uses this? from sysconfig import get_config_vars opt = " ".join(os.environ['OPT'].split()) gcv_opt = " ".join(get_config_vars('OPT')[0].split()) ccomp_s = " ".join(self.compiler_so) if opt not in ccomp_s: ccomp_s = ccomp_s.replace(gcv_opt, opt) self.compiler_so = ccomp_s.split() llink_s = " ".join(self.linker_so) if opt not in llink_s: self.linker_so = llink_s.split() + opt.split() display = '%s: %s' % (os.path.basename(self.compiler_so[0]), src) # gcc style automatic dependencies, outputs a makefile (-MF) that lists # all headers needed by a c file as a side effect of compilation (-MMD) if getattr(self, '_auto_depends', False): deps = ['-MMD', '-MF', obj + '.d'] else: deps = [] try: self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + deps + extra_postargs, display=display) except DistutilsExecError as e: msg = str(e) raise CompileError(msg) # add commandline flags to dependency file if deps: # After running the compiler, the file created will be in EBCDIC # but will not be tagged as such. This tags it so the file does not # have multiple different encodings being written to it if sys.platform == 'zos': subprocess.check_output(['chtag', '-tc', 'IBM1047', obj + '.d']) with open(obj + '.d', 'a') as f: f.write(_commandline_dep_string(cc_args, extra_postargs, pp_opts))
def to_first_supported_flag(flags: Iterable[str], compiler: CCompiler) -> str: flags = list(flags) try: return next(flag for flag in flags if is_flag_supported(flag, compiler)) except StopIteration: quote = '"{}"'.format raise CompileError('None of {flags} flags are supported ' 'by {compiler} compiler.'.format( flags=', '.join(map(quote, flags)), compiler=quote(compiler.compiler_type)))
def findPythonLib(): # try linking against the static python library libpython**.a, if this does not succeed, # try the shared library libpython**.so** or libpython**.dylib for PYTHON_LIB_FILENAME in compressList([ sysconfig.get_config_var(x) for x in ['LIBRARY', 'LDLIBRARY', 'INSTSONAME'] ]): for PYTHON_LIB_PATH in compressList( [sysconfig.get_config_var(x) for x in ['LIBPL', 'LIBDIR']]): # obtain full path to the python library PYTHON_LIB_FILEPATH = os.path.join(PYTHON_LIB_PATH, PYTHON_LIB_FILENAME) # check if the file exists at all at the given location if os.path.isfile(PYTHON_LIB_FILEPATH): # flags for compiling the shared library which serves as a Python extension module PYTHON_SO_FLAGS = [PYTHON_LIB_FILEPATH] + PYTHON_LIB_EXTRA # other libraries depend on whether this is a static or a shared python library if PYTHON_LIB_FILENAME.endswith( '.a' ) and not sysconfig.get_config_var('PYTHONFRAMEWORK'): PYTHON_SO_FLAGS += get_config_var( 'LINKFORSHARED').split() # the stack_size flag is problematic and needs to be removed PYTHON_SO_FLAGS = [ x for x in PYTHON_SO_FLAGS if not x.startswith('-Wl,-stack_size,') ] if tryPythonCode(PYTHON_SO_FLAGS): return PYTHON_SO_FLAGS, [] # successful compilation elif not PYTHON_LIB_FILENAME.endswith('.a'): # sometimes the python installation is so wrecked that the linker can find and use # the shared library libpython***.so, but this library is not in LD_LIBRARY_PATH and # cannot be found when loading the python extension module outside python itself. # the (inelegant) fix is to hardcode the path to this libpython***.so as -rpath. print("Trying rpath") RPATH = ['-Wl,-rpath,' + PYTHON_LIB_PATH ] # extend the linker options and try again if tryPythonCode(PYTHON_SO_FLAGS + RPATH): return PYTHON_SO_FLAGS + RPATH, [] if "-undefined dynamic_lookup" in sysconfig.get_config_var( 'LDSHARED'): print("Trying the last resort solution") PYTHON_SO_FLAGS = ['-undefined dynamic_lookup' ] + PYTHON_LIB_EXTRA PYTHON_EXE_FLAGS = RPATH + [PYTHON_LIB_FILEPATH] if tryPythonCode(PYTHON_SO_FLAGS, PYTHON_EXE_FLAGS): return PYTHON_SO_FLAGS, PYTHON_EXE_FLAGS # if none of the above combinations worked, give up... raise CompileError( "Could not compile test program which uses libpython" + sysconfig.get_config_var('VERSION'))
def make_out_path(p): base, ext = os.path.splitext(p) if strip_dir: base = os.path.basename(base) else: _, base = os.path.splitdrive(base) if base.startswith((os.path.sep, os.path.altsep)): base = base[1:] try: return os.path.join(output_dir, base + ext_map[ext]) except LookupError: raise CompileError("Don't know how to compile {}".format(p))
def run(self): text = self.distribution.get_long_description() # Monkeypatch docutils for simple error/warning output support utils.Reporter.system_message = system_message html = rst2html(text) # Unmonkey utils.Reporter.system_message = orignal_system_message if len(reports) > 0: raise CompileError("long_description had reST syntax errors")
def _compile(self, obj, src, *args, **kwargs): # @UnusedVariable self.compiler_so = ["gfortran"] cc_args = ['-c', '-fno-underscoring'] if sys.platform == 'darwin': self.compiler_so = _darwin_compiler_fixup(self.compiler_so, cc_args) else: cc_args.append('-fPIC') try: self.spawn(self.compiler_so + [src, '-o', obj] + cc_args) except DistutilsExecError: _, msg, _ = sys.exc_info() raise CompileError(msg)
def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): """Compile a single source files with a Unix-style compiler.""" # HP ad-hoc fix, see ticket 1383 ccomp = self.compiler_so if ccomp[0] == "aCC": # remove flags that will trigger ANSI-C mode for aCC if "-Ae" in ccomp: ccomp.remove("-Ae") if "-Aa" in ccomp: ccomp.remove("-Aa") # add flags for (almost) sane C++ handling ccomp += ["-AA"] self.compiler_so = ccomp # ensure OPT environment variable is read if "OPT" in os.environ: from distutils.sysconfig import get_config_vars opt = " ".join(os.environ["OPT"].split()) gcv_opt = " ".join(get_config_vars("OPT")[0].split()) ccomp_s = " ".join(self.compiler_so) if opt not in ccomp_s: ccomp_s = ccomp_s.replace(gcv_opt, opt) self.compiler_so = ccomp_s.split() llink_s = " ".join(self.linker_so) if opt not in llink_s: self.linker_so = llink_s.split() + opt.split() display = "%s: %s" % (os.path.basename(self.compiler_so[0]), src) # gcc style automatic dependencies, outputs a makefile (-MF) that lists # all headers needed by a c file as a side effect of compilation (-MMD) if getattr(self, "_auto_depends", False): deps = ["-MMD", "-MF", obj + ".d"] else: deps = [] try: self.spawn( self.compiler_so + cc_args + [src, "-o", obj] + deps + extra_postargs, display=display, ) except DistutilsExecError: msg = str(get_exception()) raise CompileError(msg) # add commandline flags to dependency file if deps: with open(obj + ".d", "a") as f: f.write(_commandline_dep_string(cc_args, extra_postargs, pp_opts))
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): """Compile 'src' to product 'obj'.""" src_flags = {} if is_f_file(src) and not has_f90_header(src): flavor = ":f77" compiler = self.compiler_f77 src_flags = get_f77flags(src) extra_compile_args = self.extra_f77_compile_args or [] elif is_free_format(src): flavor = ":f90" compiler = self.compiler_f90 if compiler is None: raise DistutilsExecError( "f90 not supported by %s needed for %s" % (self.__class__.__name__, src)) extra_compile_args = self.extra_f90_compile_args or [] else: flavor = ":fix" compiler = self.compiler_fix if compiler is None: raise DistutilsExecError( "f90 (fixed) not supported by %s needed for %s" % (self.__class__.__name__, src)) extra_compile_args = self.extra_f90_compile_args or [] if self.object_switch[-1] == " ": o_args = [self.object_switch.strip(), obj] else: o_args = [self.object_switch.strip() + obj] assert self.compile_switch.strip() s_args = [self.compile_switch, src] if extra_compile_args: log.info("extra %s options: %r" % (flavor[1:], " ".join(extra_compile_args))) extra_flags = src_flags.get(self.compiler_type, []) if extra_flags: log.info("using compile options from source: %r" % " ".join(extra_flags)) command = (compiler + cc_args + extra_flags + s_args + o_args + extra_postargs + extra_compile_args) display = "%s: %s" % (os.path.basename(compiler[0]) + flavor, src) try: self.spawn(command, display=display) except DistutilsExecError as e: msg = str(e) raise CompileError(msg)
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so = self.compiler_so if sys.platform == 'darwin': compiler_so = _osx_support.compiler_fixup(compiler_so, cc_args + extra_postargs) try: # iOS: since clang is not available, we send a nicer error message: if (sys.platform == 'darwin' and os.uname().machine.startswith('iP')): raise DistutilsExecError("There are no compilers available on iOS, sorry. Command was: ", cc_args) # self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg)
def compile_cxxfile(module_name, cxxfile, output_binary=None, **kwargs): '''c++ file -> native module Return the filename of the produced shared library Raises CompileError on failure ''' builddir = mkdtemp() buildtmp = mkdtemp() extension_args = make_extension(python=True, **kwargs) extension = PythranExtension(module_name, [cxxfile], **extension_args) try: setup(name=module_name, ext_modules=[extension], cmdclass={"build_ext": PythranBuildExt}, # fake CLI call script_name='setup.py', script_args=['--verbose' if logger.isEnabledFor(logging.INFO) else '--quiet', 'build_ext', '--build-lib', builddir, '--build-temp', buildtmp] ) except SystemExit as e: raise CompileError(str(e)) target, = glob.glob(os.path.join(builddir, module_name + "*")) if not output_binary: output_binary = os.path.join(os.getcwd(), module_name + os.path.splitext(target)[1]) # not using shutil.copy because it fails to copy stat across devices with open(target, 'rb') as src: with open(output_binary, 'wb') as dest: dest.write(src.read()) shutil.rmtree(builddir) shutil.rmtree(buildtmp) logger.info("Generated module: " + module_name) logger.info("Output: " + output_binary) return output_binary
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): """Compiles the source by spawning GCC and windres if needed.""" if ext == '.rc' or ext == '.res': # gcc needs '.res' and '.rc' compiled to object files !!! try: self.spawn(["windres", "-i", src, "-o", obj]) except DistutilsExecError as msg: raise CompileError(msg) elif ext == '.mc': # Adapted from msvc9compiler: # # Compile .MC to .RC file to .RES file. # * '-h dir' specifies the directory for the generated include file # * '-r dir' specifies the target directory of the generated RC file and the binary message resource it includes # # For now (since there are no options to change this), # we use the source-directory for the include file and # the build directory for the RC file and message # resources. This works at least for win32all. h_dir = os.path.dirname(src) rc_dir = os.path.dirname(obj) try: # first compile .MC to .RC and .H file self.spawn(['windmc'] + ['-h', h_dir, '-r', rc_dir] + [src]) base, _ = os.path.splitext(os.path.basename(src)) rc_file = os.path.join(rc_dir, base + '.rc') # then compile .RC to .RES file self.spawn(['windres', '-i', rc_file, '-o', obj]) except DistutilsExecError as msg: raise CompileError(msg) else: # for other files use the C-compiler try: self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg)
def make_out_path(p): base, ext = os.path.splitext(p) if strip_dir: base = os.path.basename(base) else: _, base = os.path.splitdrive(base) if base.startswith((os.path.sep, os.path.altsep)): base = base[1:] try: return base + ext_map[ext] except LookupError: # Better to raise an exception instead of silently continuing # and later complain about sources and targets having # different lengths raise CompileError("Don't know how to compile {}".format(p))
def _single_compile(obj): try: src, ext = build[obj] except KeyError: return input_opt = src # "/Tp" + src output_opt = "/Fo" + obj try: self.spawn(['cl.exe'] + compile_opts + pp_opts + [input_opt, output_opt] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg)
def findPythonLib(): PLANB_LIB = None # try linking against the static python library libpython**.a, if this does not succeed, # try the shared library libpython**.so** LIBNAMES = ['LIBRARY', 'LDLIBRARY', 'INSTSONAME'] for PYTHON_LIB_FILE in [sysconfig.get_config_var(x) for x in LIBNAMES]: for PYTHON_LIB_PATH in [ sysconfig.get_config_var(x) for x in ['LIBPL', 'LIBDIR'] ]: PYTHON_LIB_FILEPATH = os.path.join(PYTHON_LIB_PATH, PYTHON_LIB_FILE) if os.path.isfile(PYTHON_LIB_FILEPATH): # other libraries depend on whether this is a static or a shared python library PYTHON_LIB = [PYTHON_LIB_FILEPATH] + PYTHON_LIB_EXTRA if PYTHON_LIB_FILE.endswith( '.a' ) and not sysconfig.get_config_var('PYTHONFRAMEWORK'): PYTHON_LIB += get_config_var('LINKFORSHARED').split() # the stack_size flag is problematic and needs to be removed PYTHON_LIB = [ x for x in PYTHON_LIB if not x.startswith('-Wl,-stack_size,') ] result = tryPythonCode(PYTHON_LIB) if result is True: return PYTHON_LIB # successful compilation if not result and PYTHON_LIB_FILE.endswith('.so'): # sometimes the python installation is so wrecked that the linker can find and use # the shared library libpython***.so, but this library is not in LD_LIBRARY_PATH and # cannot be found when loading the python extension module outside python itself. # the (inelegant) fix is to hardcode the path to this libpython***.so as -rpath. PYTHON_LIB += ['-Wl,-rpath=' + PYTHON_LIB_PATH ] # extend the linker options result = tryPythonCode(PYTHON_LIB) # and try again if result is True: return PYTHON_LIB # now success if result: # not True, but a warning string # test compiled, but with a version mismatch warning, store it as a backup option PLANB_LIB = PYTHON_LIB PLANB_ASK = result if not PLANB_LIB is None and ask( PLANB_ASK ): # the user wants to continue with the backup option return PLANB_LIB # if none of the above combinations worked, give up... raise CompileError( "Could not compile test program which uses libpython" + sysconfig.get_config_var('VERSION'))
def run(self): # check if Makefile.local is already present if not os.path.isfile('Makefile.local') or \ not ask('Makefile.local already exists, should we use it (Y) or generate a new one (N)? '): createMakefile() # run custom build step (make) say('\n ==== Compiling the C++ library ====\n\n') if subprocess.call('make') != 0 or not os.path.isfile('agama.so'): raise CompileError("Compilation failed") if not os.path.isdir(self.build_lib): return # this occurs when running setup.py build_ext # copy the shared library and executables to the folder where the package is being built distutils.file_util.copy_file('Makefile.local', os.path.join(self.build_lib, 'agama')) distutils.file_util.copy_file('agama.so', os.path.join(self.build_lib, 'agama')) distutils.dir_util.copy_tree('exe', os.path.join(self.build_lib, 'agama', 'exe')) if os.path.isdir(EXTRAS_DIR): # this contains third-party libraries built in the process distutils.dir_util.copy_tree(EXTRAS_DIR, os.path.join(self.build_lib, 'agama', EXTRAS_DIR), verbose=False)
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): lang = self.detect_language(src) if lang == "c++": compiler = self.compiler_cxx else: compiler = self.compiler_c try: src_vms = vms.decc.to_vms(src, 0, 0)[0] obj_vms = vms.decc.to_vms(obj, 0, 0)[0] cmd_list = compiler + cc_args + pp_opts + extra_postargs + [ src_vms, '/OBJECT=' + obj_vms ] self.spawn(cmd_list) except DistutilsExecError as msg: raise CompileError(msg)
def compile_cxxfile(module_name, cxxfile, output_binary=None, **kwargs): '''c++ file -> native module Return the filename of the produced shared library Raises CompileError on failure ''' builddir = mkdtemp() buildtmp = mkdtemp() extension_args = make_extension(**kwargs) extension = Extension(module_name, [cxxfile], language="c++", **extension_args) try: setup( name=module_name, ext_modules=[extension], # fake CLI call script_name='setup.py', script_args=[ '--verbose' if logger.isEnabledFor(logging.INFO) else '--quiet', 'build_ext', '--build-lib', builddir, '--build-temp', buildtmp, ]) except SystemExit as e: raise CompileError(e.args) [target] = glob.glob(os.path.join(builddir, module_name + "*")) if not output_binary: output_binary = os.path.join(os.getcwd(), module_name + os.path.splitext(target)[1]) shutil.move(target, output_binary) shutil.rmtree(builddir) shutil.rmtree(buildtmp) logger.info("Generated module: " + module_name) logger.info("Output: " + output_binary) return output_binary
def cmd(self): """ List of arguments (str) to be passed to e.g. ``subprocess.Popen``. """ cmd = ([self.compiler_binary] + self.flags + ['-U' + x for x in self.undef] + ['-D' + x for x in self.define] + ['-I' + x for x in self.include_dirs] + self.sources) if self.run_linker: cmd += (['-L' + x for x in self.library_dirs] + ['-l' + x for x in self.libraries] + self.linkline) counted = [] for envvar in re.findall(r'\$\{(\w+)\}', ' '.join(cmd)): if os.getenv(envvar) is None: if envvar not in counted: counted.append(envvar) msg = "Environment variable '{}' undefined.".format(envvar) raise CompileError(msg) return cmd
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so = self.compiler_so compiler_so_cxx = self.compiler_so_cxx if sys.platform == 'darwin': compiler_so = _osx_support.compiler_fixup(compiler_so, cc_args + extra_postargs) compiler_so_cxx = _osx_support.compiler_fixup(compiler_so_cxx, cc_args + extra_postargs) try: if self.detect_language(src) == 'c++': self.spawn(compiler_so_cxx + cc_args + [src, '-o', obj] + extra_postargs) else: self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg)
def make_out_path(p): base, ext = os.path.splitext(p) if strip_dir: base = os.path.basename(base) else: _, base = os.path.splitdrive(base) if base.startswith((os.path.sep, os.path.altsep)): base = base[1:] try: # XXX: This may produce absurdly long paths. We should check # the length of the result and trim base until we fit within # 260 characters. return os.path.join(output_dir, base + ext_map[ext]) except LookupError: # Better to raise an exception instead of silently continuing # and later complain about sources and targets having # different lengths raise CompileError("Don't know how to compile {}".format(p))
def build_extensions(self): ct = self.compiler.compiler_type opts = self.compile_flags.get(ct, []) links = [] # Check for the presence of -fopenmp; if it's there we're good to go! if has_flags(self.compiler, ["-fopenmp"]): # Generic case, this is what GCC accepts opts += ["-fopenmp"] links += ["-lgomp"] elif has_flags(self.compiler, ["-Xpreprocessor", "-fopenmp", "-lomp"]): # Hope that clang accepts this opts += ["-Xpreprocessor", "-fopenmp", "-lomp"] links += ["-lomp"] elif has_flags(self.compiler, [ "-Xpreprocessor", "-fopenmp", "-lomp", '-I"$(brew --prefix libomp)/include"', '-L"$(brew --prefix libomp)/lib"' ]): # Case on MacOS where somebody has installed libomp using homebrew opts += [ "-Xpreprocessor", "-fopenmp", "-lomp", '-I"$(brew --prefix libomp)/include"', '-L"$(brew --prefix libomp)/lib"' ] links += ["-lomp"] else: raise CompileError( "Unable to compile C extensions on your machine, as we can't find OpenMP. " "If you are on MacOS, try `brew install libomp` and try again. " "If you are on Windows, please reach out on the GitHub and we can try " "to find a solution.") for ext in self.extensions: ext.extra_compile_args = opts ext.extra_link_args = links build_ext.build_extensions(self)
def compile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None): if not self.initialized: self.initialize() compile_info = self._setup_compile(output_dir, macros, include_dirs, sources, depends, extra_postargs) macros, objects, extra_postargs, pp_opts, build = compile_info compile_opts = extra_preargs or [] if debug: compile_opts.extend(self.compile_options_debug) else: compile_opts.extend(self.compile_options) for obj in objects: try: src, ext = build[obj] except KeyError: continue if debug: # pass the full pathname to MSVC in debug mode, # this allows the debugger to find the source file # without asking the user to browse for it src = os.path.abspath(src) input_opt = src output_opt = "-o" + obj try: self.spawn([self.cc] + compile_opts + pp_opts + [input_opt, output_opt] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg) return objects
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so = self.compiler_so arch = platform.architecture()[0].lower() if ext == ".f90": if sys.platform == 'darwin' or sys.platform == 'linux2': compiler_so = ["gfortran"] cc_args = ["-O", "-fPIC", "-c", "-ffree-form"] # Force architecture of shared library. if arch == "32bit": cc_args.append("-m32") elif arch == "64bit": cc_args.append("-m64") else: print("\nPlatform has architecture '%s' which is unknown to " "the setup script. Proceed with caution\n" % arch) try: self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg)
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): """Compile 'src' to product 'obj'.""" src_flags = {} if is_f_file(src) and not has_f90_header(src): flavor = ':f77' compiler = self.compiler_f77 src_flags = get_f77flags(src) elif is_free_format(src): flavor = ':f90' compiler = self.compiler_f90 if compiler is None: raise DistutilsExecError('f90 not supported by %s needed for %s'\ % (self.__class__.__name__,src)) else: flavor = ':fix' compiler = self.compiler_fix if compiler is None: raise DistutilsExecError('f90 (fixed) not supported by %s needed for %s'\ % (self.__class__.__name__,src)) if self.object_switch[-1]==' ': o_args = [self.object_switch.strip(),obj] else: o_args = [self.object_switch.strip()+obj] assert self.compile_switch.strip() s_args = [self.compile_switch, src] extra_flags = src_flags.get(self.compiler_type,[]) if extra_flags: log.info('using compile options from source: %r' \ % ' '.join(extra_flags)) command = compiler + cc_args + extra_flags + s_args + o_args \ + extra_postargs display = '%s: %s' % (os.path.basename(compiler[0]) + flavor, src) try: self.spawn(command,display=display) except DistutilsExecError: msg = str(get_exception()) raise CompileError(msg)