"""Сборка wheel pyfglair: вместе с python-пакетом собирается libfgl-aircon.so из корня монорепо (cmake). Метаданные — в pyproject.toml; здесь только хуки setuptools для сборки нативного ядра.""" import os from importlib.util import module_from_spec, spec_from_file_location from pathlib import Path from setuptools import Distribution, setup from setuptools.command.build_py import build_py as _build_py try: from setuptools.command.bdist_wheel import bdist_wheel as _bdist_wheel except ImportError: # setuptools < 70 from wheel.bdist_wheel import bdist_wheel as _bdist_wheel ROOT = Path(__file__).resolve().parent _COREBUILD = None def _load_corebuild(): global _COREBUILD if _COREBUILD is None: spec = spec_from_file_location( "_pyfglair_corebuild", ROOT / "pyfglair" / "_corebuild.py" ) _COREBUILD = module_from_spec(spec) spec.loader.exec_module(_COREBUILD) return _COREBUILD class build_py(_build_py): """Кладёт libfgl-aircon.so внутрь пакета до сборки wheel.""" def run(self): dest = Path(self.build_lib) / "pyfglair" dest.mkdir(parents=True, exist_ok=True) for stale in dest.glob("libfgl-aircon.*"): stale.unlink() bundled = os.environ.get("FGL_BUNDLED_MBEDTLS", "1") != "0" _load_corebuild().build_core(dest=dest, bundled_mbedtls=bundled) super().run() class BinaryDistribution(Distribution): """Платформенный wheel (внутри — .so), не py3-none-any.""" def has_ext_modules(self): return True class bdist_wheel(_bdist_wheel): """Тег py3-none-: .so собран в ABI-режиме cffi (не CPython-ABI). На musl (Alpine/HA OS) платформа заменяется на musllinux_X_Y_, иначе pip поставит glibc-сборку и dlopen упадёт. """ def get_tag(self): _, _, platform = super().get_tag() musl = _load_corebuild().musl_platform_tag() if musl is not None and platform.startswith("linux_"): platform = musl return "py3", "none", platform setup( cmdclass={"build_py": build_py, "bdist_wheel": bdist_wheel}, distclass=BinaryDistribution, )