Another approach to use zig build with setuptools.

This commit is contained in:
Leo Vasanko
2025-11-06 16:56:39 -06:00
parent fbf9c944e6
commit 9f2b931a0b
3 changed files with 51 additions and 31 deletions

View File

@@ -37,10 +37,30 @@ def _build_libaegis():
# Expose all the standard build backend hooks
get_requires_for_build_wheel = _orig.get_requires_for_build_wheel
get_requires_for_build_sdist = _orig.get_requires_for_build_sdist
prepare_metadata_for_build_wheel = _orig.prepare_metadata_for_build_wheel
build_sdist = _orig.build_sdist
def get_requires_for_build_wheel(config_settings=None):
"""Return build requirements and ensure libaegis is built first."""
_build_libaegis()
return _orig.get_requires_for_build_wheel(config_settings)
def get_requires_for_build_sdist(config_settings=None):
"""Return build requirements for sdist and ensure libaegis is built first."""
_build_libaegis()
return _orig.get_requires_for_build_sdist(config_settings)
_orig_prepare_metadata_for_build_wheel = _orig.prepare_metadata_for_build_wheel
_orig_build_sdist = _orig.build_sdist
def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
"""Prepare metadata and ensure libaegis is built (some frontends call this early)."""
_build_libaegis()
return _orig_prepare_metadata_for_build_wheel(metadata_directory, config_settings)
def build_sdist(sdist_directory, config_settings=None):
"""Build sdist, building libaegis first so the sdist can include built artifacts if needed."""
_build_libaegis()
return _orig_build_sdist(sdist_directory, config_settings)
def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):

View File

@@ -12,7 +12,6 @@ classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: Implementation :: CPython",
"License :: OSI Approved :: ISC License (ISCL)",
"Operating System :: OS Independent",
"Topic :: Security :: Cryptography",
]

View File

@@ -5,6 +5,28 @@ from pathlib import Path
from cffi import FFI
from setuptools import setup
def find_libaegis():
"""Locate libaegis.a - check common locations."""
libaegis_paths = [
Path("libaegis/zig-out/lib/libaegis.a"), # Zig build output (repo build)
Path("libaegis/build/libaegis.a"), # CMake build output (repo build)
Path("../libaegis/zig-out/lib/libaegis.a"), # When building from extracted sdist
Path("../libaegis/build/libaegis.a"), # When building from extracted sdist
Path("/usr/local/lib/libaegis.a"), # System install
Path("/usr/lib/libaegis.a"), # System install
]
for path in libaegis_paths:
if path.exists():
print(f"Found libaegis.a at: {path.resolve()}")
return str(path.resolve())
# Return None instead of raising - will be caught during build
return None
# Read the CDEF header
cdef_path = Path(__file__).parent / "pyaegis" / "aegis_cdef.h"
cdef_content = cdef_path.read_text(encoding="utf-8")
@@ -12,37 +34,16 @@ cdef_content = cdef_path.read_text(encoding="utf-8")
ffibuilder = FFI()
ffibuilder.cdef(cdef_content)
# Locate libaegis.a - check common locations
libaegis_paths = [
Path("libaegis/zig-out/lib/libaegis.a"), # Zig build output (repo build)
Path("libaegis/build/libaegis.a"), # CMake build output (repo build)
Path("../libaegis/zig-out/lib/libaegis.a"), # When building from extracted sdist
Path("../libaegis/build/libaegis.a"), # When building from extracted sdist
Path("/usr/local/lib/libaegis.a"), # System install
Path("/usr/lib/libaegis.a"), # System install
]
libaegis_static = None
for path in libaegis_paths:
if path.exists():
libaegis_static = path.resolve()
print(f"Found libaegis.a at: {libaegis_static}")
break
if not libaegis_static:
raise FileNotFoundError(
"libaegis.a not found. Please build libaegis first. "
f"Searched: {[str(p) for p in libaegis_paths]}"
)
# Include directory for headers
include_dirs = []
libaegis_include = Path("libaegis/src/include")
if libaegis_include.exists():
include_dirs.append(str(libaegis_include.resolve()))
# Set the source - we don't need any C source files since we're linking to the static library
# CFFI will generate the wrapper code automatically
# Try to find libaegis.a, but don't fail if not found (build backend will build it)
libaegis_static = find_libaegis()
# Set the source
ffibuilder.set_source(
"pyaegis._aegis", # module name
"""
@@ -55,7 +56,7 @@ ffibuilder.set_source(
#include "aegis256x4.h"
""",
include_dirs=include_dirs,
extra_objects=[str(libaegis_static)], # Link against the static library
extra_objects=[libaegis_static] if libaegis_static else [],
)
if __name__ == "__main__":