Compare commits

...

2 Commits

Author SHA1 Message Date
790e50d5c0 fix(libcomposition): atomic header install location fixed
updated to the version of libcomposition which fixes the atomic header installation directory
2026-06-12 10:53:13 -04:00
405c68bdf6 build(wheel): added auto wheel building scripts 2026-06-11 14:29:27 -04:00
10 changed files with 241 additions and 2 deletions

2
.gitignore vendored
View File

@@ -110,3 +110,5 @@ output/
scratch/
node_modules/
*.whl

View File

@@ -1,4 +1,4 @@
project('fourdst', 'cpp', version: 'v0.10.4', default_options: ['cpp_std=c++23'], meson_version: '>=1.5.0')
project('fourdst', 'cpp', version: 'v0.10.5', default_options: ['cpp_std=c++23'], meson_version: '>=1.5.0')
add_project_arguments('-fvisibility=default', language: 'cpp')

View File

@@ -34,6 +34,7 @@ fourdst-include-dirs = "fourdst:get_include_dirs"
fourdst-lib-dirs = "fourdst:get_lib_dirs"
fourdst-rpath-flags = "fourdst:get_rpath_flags"
fourdst-version = "fourdst:print_fourdst_version"
fourdst-extra-flags = "fourdst:get_extra_flags"
[tool.meson-python.args]
setup = [

View File

@@ -54,8 +54,12 @@ def get_include_flags() -> List[str]:
def get_compiler_flags() -> List[str]:
return get_include_flags() + get_lib_flags()
def get_extra_flags() -> List[str]:
return ['-fPIC', '-std=c++23']
def get_compiler_flags_formatted() -> int:
flags = get_compiler_flags()
flags.extend(get_extra_flags())
print(' '.join(flags))
return 0

View File

@@ -1,4 +1,4 @@
[wrap-git]
url = https://github.com/4D-STAR/libcomposition.git
revision = v2.4.8
revision = v2.4.9
depth = 1

View File

@@ -0,0 +1,51 @@
#!/usr/bin/env bash
set -euo pipefail
# Must be run on an aarch64 Linux host (uses docker so arm macos is fine so long as as the daemon is running)
if [[ $# -ne 1 ]]; then
echo "Usage: $0 <git-repo-url>"
echo "Example: $0 https://github.com/4D-STAR/fourdst"
exit 1
fi
REPO_URL="$1"
WORK_DIR="$(pwd)"
WHEEL_DIR="${WORK_DIR}/wheels_linux_aarch64"
echo "➤ Creating wheel output directory at ${WHEEL_DIR}"
mkdir -p "${WHEEL_DIR}"
TMPDIR="$(mktemp -d)"
echo "➤ Cloning ${REPO_URL}${TMPDIR}/project"
git clone --depth 1 "${REPO_URL}" "${TMPDIR}/project"
IMAGE="tboudreaux/manylinux_2_28_aarch64_boost_1_88_0:latest"
docker run --rm \
-v "${WHEEL_DIR}":/io/wheels \
-v "${TMPDIR}/project":/io/project \
"${IMAGE}" \
/bin/bash -eux -c '
cd /io/project
RAW=/tmp/raw_wheels
for PY in /opt/python/*/bin/python; do
"$PY" -m pip install --upgrade pip
rm -rf "$RAW"; mkdir -p "$RAW"
CC=clang CXX=clang++ "$PY" -m pip wheel . \
--no-deps \
-w "$RAW" -vv
for whl in "$RAW"/*.whl; do
auditwheel repair "$whl" -w /io/wheels
done
done
echo "Linux aarch64 wheels ready in /io/wheels"
'
echo "Done. Repaired wheels in ${WHEEL_DIR}"
rm -rf "${TMPDIR}"

View File

@@ -0,0 +1,51 @@
#!/usr/bin/env bash
set -euo pipefail
if [[ $# -ne 1 ]]; then
echo "Usage: $0 <git-repo-url>"
echo "Example: $0 https://github.com/4D-STAR/fourdst"
exit 1
fi
REPO_URL="$1"
WORK_DIR="$(pwd)"
WHEEL_DIR="${WORK_DIR}/wheels_linux_x86_64"
echo "➤ Creating wheel output directory at ${WHEEL_DIR}"
mkdir -p "${WHEEL_DIR}"
TMPDIR="$(mktemp -d)"
echo "➤ Cloning ${REPO_URL}${TMPDIR}/project"
git clone --depth 1 "${REPO_URL}" "${TMPDIR}/project"
IMAGE="tboudreaux/manylinux_2_28_x86_64_boost_1_88_0:latest"
docker run --rm \
-v "${WHEEL_DIR}":/io/wheels \
-v "${TMPDIR}/project":/io/project \
"${IMAGE}" \
/bin/bash -eux -c '
cd /io/project
RAW=/tmp/raw_wheels
for PY in /opt/python/*/bin/python; do
"$PY" -m pip install --upgrade pip
rm -rf "$RAW"; mkdir -p "$RAW"
CC=clang CXX=clang++ "$PY" -m pip wheel . \
--no-deps \
--config-settings=setup-args=-Dunity=on \
-w "$RAW" -vv
# Repair only the freshly built wheel into the shared output dir.
for whl in "$RAW"/*.whl; do
auditwheel repair "$whl" -w /io/wheels
done
done
echo "Linux x86_64 wheels ready in /io/wheels"
'
echo "Done. Repaired wheels in ${WHEEL_DIR}"
rm -rf "${TMPDIR}"

View File

@@ -0,0 +1,74 @@
#!/usr/bin/env bash
set -euo pipefail
# Must be run on an Apple Silicon (arm64) Mac.
if [[ $(uname -m) != "arm64" ]]; then
echo "Error: This script is intended to run on an Apple Silicon (arm64) Mac."
exit 1
fi
if [[ $# -ne 1 ]]; then
echo "Usage: $0 <git-repo-url>"
echo "Example: $0 https://github.com/4D-STAR/fourdst"
exit 1
fi
REPO_URL="$1"
WORK_DIR="$(pwd)"
WHEEL_DIR="${WORK_DIR}/wheels_macos_aarch64_tmp"
FINAL_WHEEL_DIR="${WORK_DIR}/wheels_macos_aarch64"
echo "➤ Creating wheel output directories"
mkdir -p "${WHEEL_DIR}"
mkdir -p "${FINAL_WHEEL_DIR}"
TMPDIR="$(mktemp -d)"
echo "➤ Cloning ${REPO_URL}${TMPDIR}/project"
git clone --depth 1 "${REPO_URL}" "${TMPDIR}/project"
cd "${TMPDIR}/project"
export MACOSX_DEPLOYMENT_TARGET=15.0
PYTHON_VERSIONS=("3.9.23" "3.10.18" "3.11.13" "3.12.11" "3.13.5" "3.13.5t" "3.14.0rc1" "3.14.0rc1t" 'pypy3.10-7.3.19' "pypy3.11-7.3.20")
if ! command -v pyenv &> /dev/null; then
echo "Error: pyenv not found. Please install it to manage Python versions."
echo " Then run installPyEnvVersions.sh to install the interpreters above."
exit 1
fi
eval "$(pyenv init -)"
for PY_VERSION in "${PYTHON_VERSIONS[@]}"; do
(
set -e
pyenv shell "${PY_VERSION}"
PY="$(pyenv which python)"
echo "----------------------------------------------------------------"
echo "➤ Building for $($PY --version) on macOS arm64"
echo "----------------------------------------------------------------"
"$PY" -m pip install --upgrade pip
"$PY" -m pip install "meson>=1.9.1,<1.10" "meson-python>=0.19,<0.20" "pybind11>=2.10" delocate
echo "➤ Building wheel with ccache enabled"
echo "➤ Found meson version $(meson --version)"
CC="ccache clang" CXX="ccache clang++" "$PY" -m pip wheel . \
--no-deps --no-build-isolation -w "${WHEEL_DIR}" -v
CURRENT_WHEEL=$(find "${WHEEL_DIR}" -name "*.whl" | head -n 1)
echo "➤ Repairing wheel with delocate"
delocate-wheel -w "${FINAL_WHEEL_DIR}" "$CURRENT_WHEEL"
rm "$CURRENT_WHEEL"
)
done
rm -rf "${TMPDIR}"
rm -rf "${WHEEL_DIR}"
echo "➤ All builds complete. Artifacts in ${FINAL_WHEEL_DIR}"

View File

@@ -0,0 +1,14 @@
#!/bin/bash
# Install every interpreter the macOS arm64 build matrix iterates over.
# Run once before build-wheels-macos_aarch64.sh.
pyenv install -s 3.9.23
pyenv install -s 3.10.18
pyenv install -s 3.11.13
pyenv install -s 3.12.11
pyenv install -s 3.13.5
pyenv install -s 3.13.5t
pyenv install -s 3.14.0rc1
pyenv install -s 3.14.0rc1t
pyenv install -s pypy3.10-7.3.19
pyenv install -s pypy3.11-7.3.20

42
utils/wheels/readme.md Normal file
View File

@@ -0,0 +1,42 @@
# Wheel Generation
This directory contains scripts to generate precompiled Python wheels for **fourdst**.
## Notes
- macOS wheels can only be generated on macOS.
- aarch64 wheels can only be generated on an aarch64 machine.
- x86_64 wheels can only be generated on an x86_64 machine.
- Linux wheels can be generated on any Linux machine, but the target architecture must match the host architecture (Docker runs natively, there is no emulation here).
- Running each script takes **a very long time** (potentially most of a day, depending on the machine) and needs roughly 2 GB of disk space.
- For the macOS build you must have all the listed Python versions installed via `pyenv`. Run `installPyEnvVersions.sh` first to install them.
- The old duplicate-RPATH workaround (`repair_wheel_macos.sh` + `fix_rpaths.py`) is **no longer needed** — the meson-python bug that caused it has been fixed, so the macOS script repairs with a plain `delocate-wheel` pass. Those two files can be deleted.
## Usage
Once you are on the correct machine, run the script for your target platform, passing the repository URL. For example, to build the macOS arm64 wheels:
```bash
./build-wheels-macos_aarch64.sh https://github.com/4D-STAR/fourdst
```
For Linux:
```bash
./build-wheels-linux_x86_64.sh https://github.com/4D-STAR/fourdst # on an x86_64 host
./build-wheels-linux_aarch64.sh https://github.com/4D-STAR/fourdst # on an aarch64 host
```
Each script writes its repaired, redistributable wheels to a per-platform directory (e.g. `wheels_macos_aarch64/`, `wheels_linux_x86_64/`).
## Publishing
Once every platform's wheels are generated (which generally requires multiple machines), copy them all into a single directory — assume it is called `wheels/` at the repository root — then, from the repository root:
```bash
python -m pip install --upgrade build twine
python -m build --sdist --outdir wheels # adds the source distribution
twine upload wheels/*
```
This uploads every wheel plus the sdist to PyPI (also slow, since it has to upload all of them).