def test_ext_suffix_override(self): """ SETUPTOOLS_EXT_SUFFIX variable always overrides default extension options. """ dist = Distribution() cmd = build_ext(dist) cmd.ext_map['for_abi3'] = ext = Extension( 'for_abi3', ['s.c'], # Override shouldn't affect abi3 modules py_limited_api=True, ) # Mock value needed to pass tests ext._links_to_dynamic = False if not IS_PYPY: expect = cmd.get_ext_filename('for_abi3') else: # PyPy builds do not use ABI3 tag, so they will # also get the overridden suffix. expect = 'for_abi3.test-suffix' try: os.environ['SETUPTOOLS_EXT_SUFFIX'] = '.test-suffix' res = cmd.get_ext_filename('normal') assert 'normal.test-suffix' == res res = cmd.get_ext_filename('for_abi3') assert expect == res finally: del os.environ['SETUPTOOLS_EXT_SUFFIX']
def testCompiler(): if not HAVE_SETUPTOOLS: # silent, we can't test without setuptools return True bitmsghash = Extension( 'bitmsghash', sources=['src/bitmsghash/bitmsghash.cpp'], libraries=['pthread', 'crypto'], ) dist = Distribution() dist.ext_modules = [bitmsghash] cmd = build_ext(dist) cmd.initialize_options() cmd.finalize_options() cmd.force = True try: cmd.run() except CompileError: return False else: fullPath = os.path.join(cmd.build_lib, cmd.get_ext_filename("bitmsghash")) return os.path.isfile(fullPath)
def test_get_ext_filename(self): # setuptools needs to give back the same # result than distutils, even if the fullname # is not in ext_map dist = Distribution() cmd = build_ext(dist) cmd.ext_map['foo/bar'] = '' res = cmd.get_ext_filename('foo') wanted = distutils_build_ext.get_ext_filename(cmd, 'foo') assert res == wanted
def get_libpython2(): d = setuptools.Distribution() b = build_ext(d) b.finalize_options() fpaths = b.library_dirs for fpath in fpaths: fpath = os.path.join(fpath, "python%s.lib" % sys.version[:3].replace('.', '')) if os.path.exists(fpath): return fpath return ""
def test_get_ext_filename(self): """ Setuptools needs to give back the same result as distutils, even if the fullname is not in ext_map. """ dist = Distribution() cmd = build_ext(dist) cmd.ext_map['foo/bar'] = '' res = cmd.get_ext_filename('foo') wanted = orig.build_ext.get_ext_filename(cmd, 'foo') assert res == wanted
def get_libpython2(): d = setuptools.Distribution() b = build_ext(d) b.finalize_options() version = "".join([str(x) for x in sys.version_info[:2]]) fpaths = b.library_dirs for fpath in fpaths: fpath = os.path.join(fpath, f"python{version}.lib") if os.path.exists(fpath): return fpath return ""
def generatePythonModuleWrapper( top_name: str, top_unique_name: str, build_dir: str, accessible_signals: List[Tuple[str, bool, bool, int]], extra_Extension_args: Dict[str, object] = DEFAULT_EXTENSION_EXTRA_ARGS): """ Collect all c/c++ files into setuptools.Extension and build it :param top_name: name of top in simulation :param top_unique_name: unique name used as name for simulator module :param build_dir: tmp directory where simulation should be build :param verilator_include_dir: include directory of Verilator :param accessible_signals: List of tuples (signal_name, signal_phy_name, read_only, is_signed, type_width) :param extra_Extension_args: additional values for setuptools.Extension constructor :return: file name of builded module (.so/.dll file) """ with working_directory(build_dir): with open("V" + top_name + "_sim_wrapper.cpp", "w") as f: f.write( verilator_sim_wrapper_template.render( module_name=top_unique_name, top_name=top_name, accessible_signals=accessible_signals)) sources = getSrcFiles(".") dist = Distribution() dist.parse_config_files() extra_Extension_args = deepcopy(extra_Extension_args) extra_Extension_args["sources"] = extra_Extension_args.get( "sources", []) + sources extra_Extension_args["include_dirs"] = extra_Extension_args.get( "include_dirs", []) + [ build_dir, ] sim = Extension( top_unique_name, **extra_Extension_args, ) dist.ext_modules = [sim] _build_ext = build_ext(dist) _build_ext.finalize_options() _build_ext.run() return os.path.join(build_dir, _build_ext.build_lib, sim._file_name)
def test_abi3_filename(self): """ Filename needs to be loadable by several versions of Python 3 if 'is_abi3' is truthy on Extension() """ print(get_abi3_suffix()) extension = Extension('spam.eggs', ['eggs.c'], py_limited_api=True) dist = Distribution(dict(ext_modules=[extension])) cmd = build_ext(dist) cmd.finalize_options() assert 'spam.eggs' in cmd.ext_map res = cmd.get_ext_filename('spam.eggs') if six.PY2 or not get_abi3_suffix(): assert res.endswith(get_config_var('SO')) elif sys.platform == 'win32': assert res.endswith('eggs.pyd') else: assert 'abi3' in res
def _build_lib(lib, dist): dist.ext_modules = [lib] _build_ext = build_ext(dist) _build_ext.finalize_options() _build_ext.run() out_lib = _build_ext.get_outputs() lib_name = lib.name lib_path = os.path.abspath(out_lib[0]) dir_name = os.path.dirname(lib_path) ext_name = os.path.splitext(lib_path)[1][1:] # print("Building:", out_lib[0]) target = os.path.join(os.path.abspath(dir_name), lib_name + "." + ext_name) if target != lib_path: _symlink_force( lib_path, os.path.join(os.path.abspath(dir_name), lib_name + "." + ext_name)) return dir_name, ext_name
import sys from setuptools.command.build_ext import build_ext from setuptools.dist import Distribution from setuptools.extension import Extension ext = Extension(sys.argv[1], []) name = build_ext(Distribution()).get_ext_filename(ext.name) sys.stdout.write(name)
def _compile(target, localfilename, fkt_name): """ Compiles a C++ function into a shared object library :param target: target folder where the .cpp file is located and where the output should be stored :param localfilename: name of file to be compiled without '.cpp' suffix :param fkt_name: name of the function to be compiled :raises Exception: An exception is raised if the file could be to compiled :return so_filename: The name of the .so file """ outfile, stdout, stderr, argv = None, None, None, sys.argv try: sys.stdout.flush(), sys.stderr.flush() outfile = open(os.path.join(target, "{0}.out".format(localfilename)), 'w') if sys.version_info[0] == 2 and isinstance(sys.stdout, file) and isinstance(sys.stdout, file): stdout, stderr = os.dup(sys.stdout.fileno()), os.dup(sys.stderr.fileno()) os.dup2(outfile.fileno(), sys.stdout.fileno()) os.dup2(outfile.fileno(), sys.stderr.fileno()) else: stdout, stderr = sys.stdout, sys.stderr sys.stdout, sys.stderr = outfile, outfile try: sources = os.path.join(target, "{0}.cpp".format(localfilename)) sys.argv = ["", "build_ext", "-b", target, #--build-lib (-b) directory for compiled extension modules "-t", "/" #--build-temp - a rel path will result in a dir structure of -b at the cur position ] # setuptools have a problem with the unicode_literals in python 2 ... if sys.version_info[0] == 2: from types import StringType localfilename = StringType(localfilename) sources = StringType(sources) setuptools.setup( \ name = localfilename\ , ext_modules = [setuptools.Extension( \ localfilename \ , sources = [sources] \ , extra_compile_args = config.cxxflags \ )] \ , include_dirs = get_numpy_include_dirs() \ ) except SystemExit as e: print(sys.stderr.write(str(e))) sys.stdout.flush(), sys.stderr.flush() finally: if isinstance(stdout, int): os.dup2(stdout, sys.stdout.fileno()), os.close(stdout) elif not stdout is None: sys.stdout = stdout if isinstance(stderr, int): os.dup2(stderr, sys.stderr.fileno()), os.close(stderr) elif not stderr is None: sys.stderr = stderr if (sys.version_info[0] == 2 and isinstance(outfile, file))\ or (sys.version_info[0] == 3 and isinstance(outfile, io.TextIOWrapper) and not outfile.closed): outfile.close() sys.argv = argv with open(os.path.join(target, "{0}.out".format(localfilename))) as outfile: out = outfile.read() # on Travis CI & Py33 name contains additional suffix to .so so_filename = build_ext(Distribution()).get_ext_filename(localfilename) if not os.path.isfile(os.path.join(target, so_filename)) or out.find("error:") > -1: print(out) raise Exception("Error compiling function {0} (compiled to {1})".format(fkt_name, target)) #TODO: add test case if out.find("warning:") > -1: #TODO: fix encoding error on *nix systems! import warnings warnings.warn("A warning has been issued during compilation:\n{0}".format(out).encode('utf-8')) if config.verbose: print(out) return so_filename
def _compile(target, localfilename, fkt_name): """ Compiles a C++ function into a shared object library :param target: target folder where the .cpp file is located and where the output should be stored :param localfilename: name of file to be compiled without '.cpp' suffix :param fkt_name: name of the function to be compiled :raises Exception: An exception is raised if the file could be to compiled :return so_filename: The name of the .so file """ outfile, stdout, stderr, argv = None, None, None, sys.argv try: sys.stdout.flush(), sys.stderr.flush() outfile = open(os.path.join(target, "{0}.out".format(localfilename)), 'w') if sys.version_info[0] == 2 and isinstance( sys.stdout, file) and isinstance(sys.stdout, file): stdout, stderr = os.dup(sys.stdout.fileno()), os.dup( sys.stderr.fileno()) os.dup2(outfile.fileno(), sys.stdout.fileno()) os.dup2(outfile.fileno(), sys.stderr.fileno()) else: stdout, stderr = sys.stdout, sys.stderr sys.stdout, sys.stderr = outfile, outfile try: sources = os.path.join(target, "{0}.cpp".format(localfilename)) sys.argv = [ "", "build_ext", "-b", target, #--build-lib (-b) directory for compiled extension modules "-t", "/" #--build-temp - a rel path will result in a dir structure of -b at the cur position ] # setuptools have a problem with the unicode_literals in python 2 ... if sys.version_info[0] == 2: from types import StringType localfilename = StringType(localfilename) sources = StringType(sources) # avoid warning on linux + gcc cfg_vars = distutils.sysconfig.get_config_vars() if "CFLAGS" in cfg_vars: cfg_vars["CFLAGS"] = cfg_vars["CFLAGS"].replace( "-Wstrict-prototypes", "") if "OPT" in cfg_vars: cfg_vars["OPT"] = cfg_vars["OPT"].replace( "-Wstrict-prototypes", "") setuptools.setup( \ name = localfilename\ , ext_modules = [setuptools.Extension( \ localfilename \ , sources = [sources] \ , extra_compile_args = config.cxxflags \ )] \ , include_dirs = get_numpy_include_dirs() \ ) except SystemExit as e: print(sys.stderr.write(str(e))) sys.stdout.flush(), sys.stderr.flush() finally: if isinstance(stdout, int): os.dup2(stdout, sys.stdout.fileno()), os.close(stdout) elif not stdout is None: sys.stdout = stdout if isinstance(stderr, int): os.dup2(stderr, sys.stderr.fileno()), os.close(stderr) elif not stderr is None: sys.stderr = stderr if (sys.version_info[0] == 2 and isinstance(outfile, file))\ or (sys.version_info[0] == 3 and isinstance(outfile, io.TextIOWrapper) and not outfile.closed): outfile.close() sys.argv = argv with open(os.path.join(target, "{0}.out".format(localfilename))) as outfile: out = outfile.read() # on Travis CI & Py33 name contains additional suffix to .so so_filename = build_ext(Distribution()).get_ext_filename(localfilename) if not os.path.isfile(os.path.join( target, so_filename)) or out.find("error:") > -1: print(out) raise Exception( "Error compiling function {0} (compiled to {1})".format( fkt_name, target)) #TODO: add test case if out.find("warning:") > -1: try: #trying to encode utf-8 to support AstroPy warnings.warn( "A warning has been issued during compilation:\n{0}".format( out).encode('utf-8')) except UnicodeError: #encoding fails on Linux warnings.warn( "A warning has been issued during compilation:\n{0}".format( out)) if config.verbose: print(out) return so_filename