156 lines
4.7 KiB
Python
156 lines
4.7 KiB
Python
import os
|
|
import sys
|
|
import shutil
|
|
import subprocess
|
|
from pathlib import Path
|
|
from importlib.machinery import EXTENSION_SUFFIXES
|
|
|
|
|
|
def install_nuitka():
|
|
print("Checking Nuitka installation...")
|
|
try:
|
|
import nuitka # noqa: F401
|
|
print("Nuitka is installed.")
|
|
except ImportError:
|
|
print("Installing Nuitka...")
|
|
subprocess.check_call(
|
|
[sys.executable, "-m", "pip", "install", "nuitka", "ordered-set", "zstandard"]
|
|
)
|
|
|
|
|
|
def get_version() -> str:
|
|
init_file = Path("src/orisys/__init__.py")
|
|
if not init_file.exists():
|
|
return "0.3.1"
|
|
for line in init_file.read_text(encoding="utf-8").splitlines():
|
|
if line.startswith("__version__"):
|
|
return line.split("=", 1)[1].strip().strip('"').strip("'")
|
|
return "0.3.1"
|
|
|
|
|
|
def find_compiled_extension(output_dir: Path) -> Path:
|
|
candidates = []
|
|
for suffix in EXTENSION_SUFFIXES:
|
|
candidates.extend(output_dir.glob(f"*{suffix}"))
|
|
if not candidates:
|
|
all_files = ", ".join(p.name for p in output_dir.iterdir()) if output_dir.exists() else "(none)"
|
|
raise RuntimeError(f"Nuitka did not produce a compiled extension. Found: {all_files}")
|
|
# Prefer the shortest filename (usually the package extension itself)
|
|
return sorted(candidates, key=lambda p: len(p.name))[0]
|
|
|
|
|
|
def build():
|
|
install_nuitka()
|
|
|
|
version = get_version()
|
|
src_dir = Path("src/orisys")
|
|
output_dir = Path("build_nuitka")
|
|
dist_dir = Path("dist_nuitka")
|
|
|
|
if output_dir.exists():
|
|
shutil.rmtree(output_dir)
|
|
if dist_dir.exists():
|
|
shutil.rmtree(dist_dir)
|
|
output_dir.mkdir()
|
|
dist_dir.mkdir()
|
|
|
|
print("\n=== Compiling with Nuitka ===")
|
|
env = os.environ.copy()
|
|
env["PYTHONPATH"] = "src" + os.pathsep + env.get("PYTHONPATH", "")
|
|
|
|
cmd = [
|
|
sys.executable, "-m", "nuitka",
|
|
"--module",
|
|
"--include-package=orisys",
|
|
"--output-dir=" + str(output_dir),
|
|
"--remove-output",
|
|
"--no-pyi-file",
|
|
"src/orisys",
|
|
]
|
|
print(f"Running: {' '.join(cmd)}")
|
|
subprocess.check_call(cmd, env=env)
|
|
|
|
ext_file = find_compiled_extension(output_dir)
|
|
ext_suffix = "".join(ext_file.suffixes)
|
|
print(f"Generated compiled extension: {ext_file}")
|
|
|
|
print("\n=== Preparing Wheel Structure ===")
|
|
wheel_root = dist_dir / "wheel_root"
|
|
pkg_dir = wheel_root / "orisys"
|
|
pkg_dir.mkdir(parents=True)
|
|
|
|
dest_ext = pkg_dir / f"__init__{ext_suffix}"
|
|
shutil.copy(ext_file, dest_ext)
|
|
print(f"Copied compiled package to {dest_ext}")
|
|
|
|
configs_src = src_dir / "configs"
|
|
configs_dst = pkg_dir / "configs"
|
|
configs_dst.mkdir()
|
|
json_count = 0
|
|
for json_file in configs_src.glob("*.json"):
|
|
shutil.copy(json_file, configs_dst)
|
|
json_count += 1
|
|
print(f"Copied {json_count} JSON config files")
|
|
|
|
examples_dst = pkg_dir / "examples"
|
|
examples_dst.mkdir(exist_ok=True)
|
|
(examples_dst / "__init__.py").write_text("# Examples for orisys package\n", encoding="utf-8")
|
|
example_files = [Path("example1_basic_pipeline.py"), Path("example2_two_sensor_pipeline.py")]
|
|
example_count = 0
|
|
for example_file in example_files:
|
|
if example_file.exists():
|
|
shutil.copy(example_file, examples_dst)
|
|
example_count += 1
|
|
print(f"Copied example: {example_file.name}")
|
|
print(f"Copied {example_count} example files to orisys/examples/")
|
|
|
|
setup_py_path = dist_dir / "setup.py"
|
|
setup_content = f"""
|
|
from setuptools import setup, Distribution
|
|
|
|
class BinaryDistribution(Distribution):
|
|
def has_ext_modules(self):
|
|
return True
|
|
|
|
setup(
|
|
name="orisys",
|
|
version="{version}",
|
|
description="Orisys - Optical Tactile Sensor SDK (Nuitka Compiled)",
|
|
author="Orisys",
|
|
packages=['orisys', 'orisys.examples'],
|
|
package_dir={{'': 'wheel_root'}},
|
|
package_data={{
|
|
'orisys': ['*{ext_suffix}', 'configs/*.json'],
|
|
'orisys.examples': ['*.py'],
|
|
}},
|
|
include_package_data=True,
|
|
install_requires=[
|
|
"numpy>=1.24.4",
|
|
"opencv-python>=4.10.0.84",
|
|
"scipy>=1.10.1",
|
|
],
|
|
extras_require={{
|
|
"cuda12": ["cupy-cuda12x>=12.3.0"],
|
|
"cuda13": ["cupy-cuda13x>=13.0.0"],
|
|
"cuda": ["cupy-cuda12x>=12.3.0"],
|
|
}},
|
|
distclass=BinaryDistribution,
|
|
zip_safe=False,
|
|
)
|
|
"""
|
|
setup_py_path.write_text(setup_content, encoding="utf-8")
|
|
|
|
print("\n=== Building Wheel ===")
|
|
subprocess.check_call([sys.executable, "setup.py", "bdist_wheel"], cwd=dist_dir)
|
|
|
|
wheels = list((dist_dir / "dist").glob("*.whl"))
|
|
if wheels:
|
|
print(f"\n[SUCCESS] Wheel created: {wheels[0]}")
|
|
else:
|
|
print("\n[ERROR] Wheel not found.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
build()
|
|
|