Build cleanup, pathname reorganisation, cdef to repository (although generated with gen_cdef.py).
This commit is contained in:
+10
-64
@@ -1,33 +1,13 @@
|
||||
"""Dynamic loader for libaegis using CFFI (ABI mode).
|
||||
|
||||
This module loads the shared library bundled with the package.
|
||||
|
||||
Exports:
|
||||
- ffi: a cffi.FFI instance with the libaegis API declared
|
||||
- lib: the loaded libaegis shared library (ffi.dlopen)
|
||||
- libc: the C runtime (for posix_memalign/free on POSIX)
|
||||
- alloc_aligned(size, alignment): return (void*) pointer with requested alignment
|
||||
"""
|
||||
"""Dynamic loader for libaegis using CFFI (ABI mode)."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from cffi import FFI
|
||||
|
||||
ffi = FFI()
|
||||
|
||||
# Load CFFI cdef declarations from text file
|
||||
cdef_path = os.path.join(os.path.dirname(__file__), "build", "aegis_cdef.h")
|
||||
with open(cdef_path, "r", encoding="utf-8") as f:
|
||||
cdef_content = f.read()
|
||||
ffi.cdef(cdef_content)
|
||||
|
||||
try:
|
||||
# ctypes is only used to resolve libc reliably across platforms
|
||||
import ctypes.util as _ctypes_util # type: ignore
|
||||
except Exception: # pragma: no cover - very unlikely to happen
|
||||
_ctypes_util = None # type: ignore[assignment]
|
||||
__ALL__ = ["ffi", "lib"]
|
||||
|
||||
|
||||
def _platform_lib_name() -> str:
|
||||
@@ -39,52 +19,18 @@ def _platform_lib_name() -> str:
|
||||
|
||||
|
||||
def _load_libaegis():
|
||||
pkg_dir = os.path.dirname(__file__)
|
||||
candidate = os.path.join(pkg_dir, "build", _platform_lib_name())
|
||||
if os.path.exists(candidate):
|
||||
pkg_dir = Path(__file__).parent
|
||||
candidate = pkg_dir / "build" / _platform_lib_name()
|
||||
if candidate.exists():
|
||||
try:
|
||||
return ffi.dlopen(candidate)
|
||||
return ffi.dlopen(str(candidate))
|
||||
except Exception as e:
|
||||
raise OSError(f"Failed to load libaegis from {candidate}: {e}")
|
||||
else:
|
||||
raise OSError(f"Could not find libaegis at {candidate}")
|
||||
|
||||
|
||||
def _load_libc():
|
||||
# Use ctypes.util to find a usable libc name; fallback to None-dlopen on POSIX
|
||||
if _ctypes_util is not None:
|
||||
libc_name = _ctypes_util.find_library("c") # type: ignore[attr-defined]
|
||||
if libc_name:
|
||||
try:
|
||||
return ffi.dlopen(libc_name)
|
||||
except Exception:
|
||||
pass
|
||||
# Fallback: try process globals (works on many Unix platforms)
|
||||
try:
|
||||
return ffi.dlopen(None)
|
||||
except Exception as e:
|
||||
raise OSError(f"Unable to load libc for aligned allocation: {e}")
|
||||
|
||||
|
||||
ffi = FFI()
|
||||
ffi.cdef(Path(__file__).with_name("aegis_cdef.h").read_text(encoding="utf-8"))
|
||||
lib: Any = _load_libaegis()
|
||||
libc: Any = _load_libc()
|
||||
|
||||
# Initialize CPU feature selection (recommended by the library)
|
||||
try:
|
||||
lib.aegis_init()
|
||||
except Exception:
|
||||
# Non-fatal; functions will still work, maybe slower
|
||||
pass
|
||||
|
||||
|
||||
def alloc_aligned(size: int, alignment: int = 64):
|
||||
"""Allocate aligned memory via posix_memalign(); returns a void* cdata.
|
||||
|
||||
The returned pointer must be freed with libc.free(). Attach a GC finalizer
|
||||
at call sites using ffi.gc(ptr, libc.free) after casting to the target type.
|
||||
"""
|
||||
memptr = ffi.new("void **")
|
||||
rc = libc.posix_memalign(memptr, alignment, size)
|
||||
if rc != 0 or memptr[0] == ffi.NULL:
|
||||
raise MemoryError(f"posix_memalign({alignment}, {size}) failed with rc={rc}")
|
||||
return memptr[0]
|
||||
lib.aegis_init()
|
||||
|
||||
Reference in New Issue
Block a user