Repository navigation
Expand file tree
/
Copy pathsetup.py
More file actions
104 lines (76 loc) · 3.07 KB
/
Copy pathsetup.py
File metadata and controls
104 lines (76 loc) · 3.07 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
from __future__ import annotations
from pathlib import Path
from setuptools import Distribution
from setuptools import setup
from setuptools.command.bdist_wheel import bdist_wheel as _bdist_wheel
from setuptools.command.build_py import build_py as _build_py
SCIPY_OPENBLAS64_DIST = "scipy-openblas64"
TARGET_LIB_DIR = "netgen_mesher.libs"
def _is_runtime_library(path: Path) -> bool:
suffix = path.suffix.lower()
return suffix in {".dll", ".dylib"} or ".so" in path.suffixes
def _scipy_openblas64_dist():
try:
from importlib import metadata
except ImportError: # pragma: no cover - Python < 3.8 fallback
import importlib_metadata as metadata
return metadata.distribution(SCIPY_OPENBLAS64_DIST)
def _scipy_openblas64_platform_tag(default: str) -> str:
wheel_metadata = _scipy_openblas64_dist().read_text("WHEEL") or ""
platform_tags: list[str] = []
for line in wheel_metadata.splitlines():
if not line.startswith("Tag: "):
continue
tag_parts = line.removeprefix("Tag: ").strip().split("-")
if len(tag_parts) == 3 and tag_parts[0] == "py3" and tag_parts[1] == "none":
platform_tags.append(tag_parts[2])
return ".".join(dict.fromkeys(platform_tags)) or default
class build_py(_build_py):
def run(self):
super().run()
self._copy_runtime_libraries()
self._copy_third_party_license()
def _copy_runtime_libraries(self) -> None:
from scipy_openblas64 import get_lib_dir
source_dir = Path(get_lib_dir())
target_dir = Path(self.build_lib, TARGET_LIB_DIR)
target_dir.mkdir(parents=True, exist_ok=True)
libraries = sorted(
path
for path in source_dir.iterdir()
if path.is_file() and _is_runtime_library(path)
)
if not libraries:
raise RuntimeError(f"No runtime libraries found in {source_dir}")
for library in libraries:
self.copy_file(str(library), str(target_dir / library.name))
def _copy_third_party_license(self) -> None:
dist = _scipy_openblas64_dist()
files = dist.files or []
license_files = [
dist.locate_file(file)
for file in files
if file.name == "LICENSE.txt" and "licenses" in file.parts
]
if not license_files:
return
package_dir = Path(self.build_lib, "ngsolve_openblas")
package_dir.mkdir(parents=True, exist_ok=True)
self.copy_file(str(license_files[0]), str(package_dir / "SCIPY_OPENBLAS64_LICENSE.txt"))
class bdist_wheel(_bdist_wheel):
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
_python_tag, _abi_tag, platform_tag = super().get_tag()
return "py3", "none", _scipy_openblas64_platform_tag(platform_tag)
class BinaryDistribution(Distribution):
def has_ext_modules(self) -> bool:
return True
setup(
distclass=BinaryDistribution,
cmdclass={
"build_py": build_py,
"bdist_wheel": bdist_wheel,
},
)