Compare commits

...

3 Commits

Author SHA1 Message Date
ef840c07ea fix(pybind): pinned pybind to 3.0.0 for ABI compatibility 2026-06-12 14:00:40 -04:00
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
13 changed files with 276 additions and 13 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.6', default_options: ['cpp_std=c++23'], meson_version: '>=1.5.0')
add_project_arguments('-fvisibility=default', language: 'cpp')

View File

@@ -1,5 +1,5 @@
[build-system]
requires = ["meson-python>=0.19,<0.20", "meson>=1.9.1,<1.10", "pybind11>=2.10"]
requires = ["meson-python>=0.19,<0.20", "meson>=1.9.1,<1.10", "pybind11==3.0.0"]
build-backend = "mesonpy"
[project]
@@ -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,19 @@
Copyright (c) 2021 The Meson development team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,8 @@
project('pybind11', 'cpp',
version : 'v3.0.0',
license : 'BSD-3-Clause')
pybind11_incdir = include_directories('include')
pybind11_dep = declare_dependency(
include_directories : pybind11_incdir)

View File

@@ -1,13 +1,8 @@
[wrap-file]
directory = pybind11-2.13.5
source_url = https://github.com/pybind/pybind11/archive/refs/tags/v2.13.5.tar.gz
source_filename = pybind11-2.13.5.tar.gz
source_hash = b1e209c42b3a9ed74da3e0b25a4f4cd478d89d5efbb48f04b277df427faf6252
patch_filename = pybind11_2.13.5-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/pybind11_2.13.5-1/get_patch
patch_hash = ecb031b830481560b3d8487ed63ba4f5509a074be42f5d19af64d844c795e15b
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/pybind11_2.13.5-1/pybind11-2.13.5.tar.gz
wrapdb_version = 2.13.5-1
[wrap-git]
url = https://github.com/pybind/pybind11.git
revision = v3.0.0
depth = 1
patch_directory = pybind11
[provide]
pybind11 = pybind11_dep

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" "3.14-dev" "3.14t-dev" )
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,16 @@
#!/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 3.14-dev
pyenv install -s 3.14t-dev
pyenv install -s 3.15-dev
pyenv install -s 3.15t-dev

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).