From cd41945e3a38e14c6aadbde988382bc58318a0c1 Mon Sep 17 00:00:00 2001 From: Garrett Barter Date: Sun, 7 Jan 2024 17:25:47 -0700 Subject: [PATCH] revert back to prior setup style --- setup.py | 157 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 84 insertions(+), 73 deletions(-) diff --git a/setup.py b/setup.py index db3be24..478e459 100644 --- a/setup.py +++ b/setup.py @@ -1,10 +1,14 @@ #!/usr/bin/env python +# encoding: utf-8 + +# setup.py +# only if building in place: ``python setup.py build_ext --inplace`` import os import re -import shutil import platform +import shutil import setuptools -from setuptools.command.build_ext import build_ext +import subprocess ####### # This forces wheels to be platform specific @@ -21,86 +25,93 @@ class BinaryDistribution(Distribution): def has_ext_modules(foo): return True ####### -this_dir = os.path.abspath(os.path.dirname(__file__)) -build_dir = os.path.join(this_dir, "build") + + +def run_meson_build(staging_dir): + prefix = os.path.join(os.getcwd(), staging_dir) + purelibdir = "." + + # check if meson extra args are specified + meson_args = "" + if "MESON_ARGS" in os.environ: + meson_args = os.environ["MESON_ARGS"] + # A weird add-on on mac github action runners needs to be removed + if meson_args.find("buildtype") >= 0: meson_args = "" + + if platform.system() == "Windows": + if not "FC" in os.environ: + os.environ["FC"] = "gfortran" + if not "CC" in os.environ: + os.environ["CC"] = "gcc" + + # configure + meson_path = shutil.which("meson") + if meson_path is None: + raise OSError("The meson command cannot be found on the system") + + meson_call = [meson_path, "setup", staging_dir, "--wipe", + f"--prefix={prefix}", f"-Dpython.purelibdir={purelibdir}", + f"-Dpython.platlibdir={purelibdir}", meson_args] + meson_call = [m for m in meson_call if m != ""] + print(meson_call) + p1 = subprocess.run(meson_call, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + os.makedirs(staging_dir, exist_ok=True) + setup_log = os.path.join(staging_dir, "setup.log") + with open(setup_log, "wb") as f: + f.write(p1.stdout) + if p1.returncode != 0: + with open(setup_log, "r") as f: + print(f.read()) + raise OSError(meson_call, f"The meson setup command failed! Check the log at {setup_log} for more information.") + + # build + meson_call = [meson_path, "compile", "-vC", staging_dir] + meson_call = [m for m in meson_call if m != ""] + print(meson_call) + p2 = subprocess.run(meson_call, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + compile_log = os.path.join(staging_dir, "compile.log") + with open(compile_log, "wb") as f: + f.write(p2.stdout) + if p2.returncode != 0: + with open(compile_log, "r") as f: + print(f.read()) + raise OSError(meson_call, f"The meson compile command failed! Check the log at {compile_log} for more information.") + def copy_shared_libraries(): - build_path = os.path.join(build_dir, "ccblade") + build_path = os.path.join(staging_dir, "ccblade") for root, _dirs, files in os.walk(build_path): for file in files: - # move ccblade libraries to just under staging_dir - if file.endswith((".so", ".lib", ".pyd", ".pdb", ".dylib", ".dll")): + # move ccblade to just under staging_dir + if file.endswith((".so", ".lib", ".pyd", ".pdb", ".dylib", ".dll", ".mod")): if ".so.p" in root or ".pyd.p" in root: # excludes intermediate object files continue file_path = os.path.join(root, file) new_path = str(file_path) - match = re.search(build_dir, new_path) + match = re.search(staging_dir, new_path) new_path = new_path[match.span()[1] + 1 :] print(f"Copying build file {file_path} -> {new_path}") - shutil.copy(file_path, new_path) + shutil.move(file_path, new_path) + -####### -class MesonExtension(setuptools.Extension): - - def __init__(self, name, sourcedir="", **kwa): - setuptools.Extension.__init__(self, name, sources=[], **kwa) - self.sourcedir = os.path.abspath(sourcedir) - -class MesonBuildExt(build_ext): - - def copy_extensions_to_source(self): - newext = [] - for ext in self.extensions: - if isinstance(ext, MesonExtension): continue - newext.append( ext ) - self.extensions = newext - super().copy_extensions_to_source() - - def build_extension(self, ext): - if not isinstance(ext, MesonExtension): - super().build_extension(ext) - - else: - - # Ensure that Meson is present and working - try: - self.spawn(["meson", "--version"]) - except OSError: - raise RuntimeError("Cannot find meson executable") - - # check if meson extra args are specified - meson_args = "" - if "MESON_ARGS" in os.environ: - meson_args = os.environ["MESON_ARGS"] - - if platform.system() == "Windows": - if "FC" not in os.environ: - os.environ["FC"] = "gfortran" - if "CC" not in os.environ: - os.environ["CC"] = "gcc" - - purelibdir = "." - configure_call = ["meson", "setup", build_dir, "--wipe", - f"-Dpython.purelibdir={purelibdir}", f"--prefix={build_dir}", - f"-Dpython.platlibdir={purelibdir}"] + meson_args.split() - configure_call = [m for m in configure_call if m.strip() != ""] - print(configure_call) - - build_call = ["meson", "compile", "-vC", build_dir] - print(build_call) - - self.build_temp = build_dir - - # Need fresh build directory for CMake - os.makedirs(self.build_temp, exist_ok=True) - - self.spawn(configure_call) - self.spawn(build_call) - copy_shared_libraries() - - if __name__ == "__main__": - setuptools.setup(cmdclass={"bdist_wheel": bdist_wheel, "build_ext": MesonBuildExt}, - distclass=BinaryDistribution, - ext_modules=[ MesonExtension("ccblade", this_dir) ], - ) + # This is where the meson build system will install to, it is then + # used as the sources for setuptools + staging_dir = "meson_build" + + # this keeps the meson build system from running more than once + if "dist" not in str(os.path.abspath(__file__)): + cwd = os.getcwd() + run_meson_build(staging_dir) + os.chdir(cwd) + copy_shared_libraries() + + init_file = os.path.join("ccblade", "__init__.py") + #__version__ = re.findall( + # r"""__version__ = ["']+([0-9\.]*)["']+""", + # open(init_file).read(), + #)[0] + + setuptools.setup(cmdclass={'bdist_wheel': bdist_wheel}, distclass=BinaryDistribution) + +#os.environ['NPY_DISTUTILS_APPEND_FLAGS'] = '1'