diff --git a/setup.py b/setup.py index bf344b5e..f1a44510 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,8 @@ #!/usr/bin/env python3 +from glob import glob import os import platform +import shutil import struct import subprocess import sys @@ -9,7 +11,8 @@ ROOT_DIR = os.path.abspath(os.path.dirname(__file__)) -BUILD_DIR = os.path.join(ROOT_DIR, "build", "native") +TARGET_BUILD_DIR = os.path.join(ROOT_DIR, "build", "native") +HOST_BUILD_DIR = os.path.join(ROOT_DIR, "build", "native", "host") class BuildExtension(build_ext): @@ -23,14 +26,19 @@ def run(self): except OSError as exc: raise RuntimeError("Please install CMake to build") from exc + # When building pypcode wheels on GitHub Actions using CIBuildWheel, ARCHFLAGS will be set + CROSS_COMPILING_FOR_MACOS_ARM64 = ( + platform.system() == "Darwin" and platform.machine() == "x86_64" and "arm64" in os.getenv("ARCHFLAGS", "") + ) + CROSS_COMPILING = CROSS_COMPILING_FOR_MACOS_ARM64 + install_pkg_root = os.path.abspath(os.path.join(ROOT_DIR if self.inplace else self.build_lib, "pypcode")) cmake_install_prefix = install_pkg_root cmake_config_args = [ f"-DCMAKE_INSTALL_PREFIX={cmake_install_prefix}", f"-DPython_EXECUTABLE={sys.executable}", - f"-D CMAKE_OSX_DEPLOYMENT_TARGET=10.14", - f"-D CMAKE_OSX_ARCHITECTURES=arm64", ] + cmake_build_args = [] if platform.system() == "Windows": is_64b = struct.calcsize("P") * 8 == 64 @@ -38,16 +46,41 @@ def run(self): cmake_build_args += ["--config", "Release"] # Build sleigh and pypcode_native extension - subprocess.check_call(["cmake", "-S", ".", "-B", BUILD_DIR] + cmake_config_args, cwd=ROOT_DIR) + target_cmake_config_args = cmake_config_args[::] + if CROSS_COMPILING_FOR_MACOS_ARM64: + target_cmake_config_args += [ + f"-DCMAKE_OSX_DEPLOYMENT_TARGET=10.14", + f"-DCMAKE_OSX_ARCHITECTURES=arm64", + ] + subprocess.check_call(["cmake", "-S", ".", "-B", TARGET_BUILD_DIR] + target_cmake_config_args, cwd=ROOT_DIR) subprocess.check_call( - ["cmake", "--build", BUILD_DIR, "--parallel", "--verbose"] + cmake_build_args, + ["cmake", "--build", TARGET_BUILD_DIR, "--parallel", "--verbose"] + cmake_build_args, cwd=ROOT_DIR, ) - subprocess.check_call(["cmake", "--install", BUILD_DIR], cwd=ROOT_DIR) - # Build sla files + if CROSS_COMPILING: + # Also build a host version of sleigh to process .sla files + host_cmake_config_args = cmake_config_args[::] + subprocess.check_call(["cmake", "-S", ".", "-B", HOST_BUILD_DIR] + host_cmake_config_args, cwd=ROOT_DIR) + subprocess.check_call( + ["cmake", "--build", HOST_BUILD_DIR, "--parallel", "--verbose", "--target", "sleigh"] + + cmake_build_args, + cwd=ROOT_DIR, + ) + bin_ext = ".exe" if platform.system() == "Windows" else "" - sleigh_bin = os.path.join(install_pkg_root, "bin", "sleigh" + bin_ext) + install_pkg_bin_dir = os.path.join(install_pkg_root, "bin") + os.makedirs(install_pkg_bin_dir, exist_ok=True) + + # Install extension and sleigh binary + module_filename = glob("pypcode_native.*", root_dir=TARGET_BUILD_DIR)[0] + sleigh_filename = "sleigh" + bin_ext + shutil.copy(os.path.join(TARGET_BUILD_DIR, sleigh_filename), os.path.join(install_pkg_bin_dir, sleigh_filename)) + shutil.copy(os.path.join(TARGET_BUILD_DIR, module_filename), os.path.join(install_pkg_root, module_filename)) + + # Build sla files + host_bin_root = HOST_BUILD_DIR if CROSS_COMPILING_FOR_MACOS_ARM64 else install_pkg_bin_dir + sleigh_bin = os.path.join(host_bin_root, sleigh_filename) specfiles_dir = os.path.join(install_pkg_root, "processors") subprocess.check_call([sleigh_bin, "-a", specfiles_dir])