-
Notifications
You must be signed in to change notification settings - Fork 85
Expand file tree
/
Copy pathsetup.py
More file actions
118 lines (102 loc) · 4.67 KB
/
setup.py
File metadata and controls
118 lines (102 loc) · 4.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import os
import sys
import shutil
import subprocess
import glob
from pathlib import Path
from setuptools import Extension, setup
from setuptools.command.build_ext import build_ext
def resolve_path(path: str) -> str:
return os.path.abspath(path)
class CMakeExtension(Extension):
def __init__(self, name: str, sourcedir: str = '.', **kwa) -> None:
super().__init__(name, sources=[], **kwa)
self.sourcedir = resolve_path(sourcedir)
class CMakeBuild(build_ext):
def build_extension(self, ext: CMakeExtension) -> None:
if not self._copy_externally_built(ext):
self._build_with_cmake(ext)
def _copy_externally_built(self, ext: CMakeExtension) -> bool:
target_path = resolve_path(self.get_ext_fullpath(ext.name))
ext_filename = os.path.basename(target_path)
source_path = os.path.join(ext.sourcedir, ext_filename)
if os.path.isfile(source_path):
os.makedirs(os.path.dirname(target_path), exist_ok=True)
shutil.copyfile(source_path, target_path)
return True
else:
return False
def _build_with_cmake(self, ext: CMakeExtension) -> None:
# Must be in this form due to bug in .resolve() only fixed in Python 3.10+
ext_fullpath = Path.cwd() / self.get_ext_fullpath(ext.name)
extdir = ext_fullpath.parent.resolve()
debug = int(os.environ.get("DEBUG", 0)) if self.debug is None else self.debug
cfg = "Debug" if debug else "Release"
local_prefix = os.path.join(os.path.expanduser('~'), ".local")
cmake_args = [
f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={extdir}{os.sep}",
f"-DPython3_EXECUTABLE={sys.executable}",
f"-DCMAKE_BUILD_TYPE={cfg}",
f"-DCMAKE_PREFIX_PATH={local_prefix}"
]
build_args = []
# Adding CMake arguments set as environment variable
if "CMAKE_ARGS" in os.environ:
cmake_args += [item for item in os.environ["CMAKE_ARGS"].split(" ") if item]
# Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level
# across all generators.
if "CMAKE_BUILD_PARALLEL_LEVEL" not in os.environ:
# self.parallel is a Python 3 only way to set parallel jobs by hand
# using -j in the build_ext call, not supported by pip or PyPA-build.
if hasattr(self, "parallel") and self.parallel:
# CMake 3.12+ only.
build_args += [f"-j{self.parallel}"]
build_temp = Path(self.build_temp) / ext.name
if not build_temp.exists():
build_temp.mkdir(parents=True)
subprocess.run(
["conan", "install", ext.sourcedir, "--output-folder=.",
"--build=missing"], cwd=build_temp, check=True
)
if os.name == 'nt':
dcmake_toolchain_file_path = f"{build_temp}/build/generators/conan_toolchain.cmake"
else:
dcmake_toolchain_file_path = f"./build/{cfg}/generators/conan_toolchain.cmake"
subprocess.run(
["cmake", ext.sourcedir,
f"-DCMAKE_TOOLCHAIN_FILE={dcmake_toolchain_file_path}", *cmake_args],
cwd=build_temp, check=True
)
subprocess.run(
["cmake", "--build", ".", *build_args], cwd=build_temp, check=True
)
if os.name == 'nt':
import platform
bin_dir = ".\\"
current_python_version = sys.version.split(" ")[0].split(".")
machine = platform.machine().lower()
_platform = platform.python_implementation()
if _platform == "CPython":
_pyd = f"hyperonpy.cp{current_python_version[0]}{current_python_version[1]}*{machine}*.pyd"
elif _platform == "PyPy":
_pyd = f"hyperonpy.pypy{current_python_version[0]}{current_python_version[1]}*{machine}*.pyd"
else:
raise Exception("Unknown python implementation") # should be unreachable except new implementation appears in the future.
pyd_file = glob.glob(os.path.join(bin_dir, _pyd))
shutil.copyfile(pyd_file[0], ext_fullpath)
def get_version(rel_path):
try:
with open(rel_path) as f: ver = f.read().splitlines()[0].split("'")[1]
return ver
except Exception:
print(f"Error reading file {rel_path}", file=sys.stderr)
def version_scheme(*args):
return get_version("./VERSION")
setup(
ext_modules=[CMakeExtension("hyperonpy")],
cmdclass={"build_ext": CMakeBuild},
url="https://github.com/trueagi-io/hyperon-experimental",
use_scm_version={'root': '..',
'version_scheme': version_scheme,
'version_file': './hyperon/_version.py'},
)