default md5.h to define function prototypes #316
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build Wheels | |
| on: | |
| push: | |
| branches: [ public, mesonify ] | |
| tags: | |
| - v* | |
| pull_request: | |
| branches: [ public, mesonify ] | |
| # Allows you to run this workflow manually from the Actions tab | |
| workflow_dispatch: | |
| jobs: | |
| build_wheels: | |
| name: Build wheels (${{ matrix.name }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Linux with manylinux2014 for Python 3.9-3.10 (broader compatibility) | |
| - name: linux-manylinux2014 | |
| os: ubuntu-latest | |
| manylinux_image: manylinux2014 | |
| cibw_build: "cp39-manylinux* cp310-manylinux*" | |
| before_all: "yum install -y openblas-devel lapack-devel netcdf-devel hdf5-devel" | |
| # Linux with manylinux_2_28 for Python 3.11+ (scipy compatibility) | |
| - name: linux-manylinux_2_28 | |
| os: ubuntu-latest | |
| manylinux_image: manylinux_2_28 | |
| cibw_build: "cp311-manylinux* cp312-manylinux* cp313-manylinux*" | |
| before_all: "dnf install -y epel-release && dnf install -y openblas-devel lapack-devel" | |
| # macOS ARM64 | |
| - name: macos-arm64 | |
| os: macos-14 | |
| # macOS x86_64 | |
| - name: macos-x86_64 | |
| os: macos-15-intel | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: 'recursive' | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.x' | |
| - name: Install cibuildwheel | |
| run: python -m pip install cibuildwheel==2.21.1 | |
| - name: Set version from git tag | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| run: | | |
| VERSION="${GITHUB_REF#refs/tags/v}" | |
| echo "Setting version to $VERSION from tag" | |
| echo "$VERSION" > quippy/VERSION | |
| # Update meson.build version (meson-python reads from project() call) | |
| # Only update the project version line, not meson_version | |
| sed -i.bak "s/^ version: '[^']*'/ version: '$VERSION'/" quippy/meson.build | |
| rm -f quippy/meson.build.bak | |
| echo "Updated quippy/meson.build:" | |
| head -5 quippy/meson.build | |
| - name: Determine architecture and deployment target | |
| id: arch | |
| run: | | |
| if [ "$RUNNER_OS" == "Linux" ]; then | |
| echo "arch=x86_64" >> $GITHUB_OUTPUT | |
| elif [ "$RUNNER_OS" == "macOS" ]; then | |
| # macos-15-intel is x86_64, macos-14 is arm64 | |
| if [[ "${{ matrix.os }}" == "macos-14" ]]; then | |
| echo "arch=arm64" >> $GITHUB_OUTPUT | |
| echo "macos_target=14.0" >> $GITHUB_OUTPUT | |
| else | |
| echo "arch=x86_64" >> $GITHUB_OUTPUT | |
| echo "macos_target=15.0" >> $GITHUB_OUTPUT | |
| fi | |
| fi | |
| - name: Install build dependencies | |
| run: | | |
| if [ "$RUNNER_OS" == "Linux" ]; then | |
| sudo apt-get update | |
| sudo apt-get install -y gfortran ninja-build pkg-config libopenblas-dev liblapack-dev libnetcdf-dev libhdf5-dev | |
| elif [ "$RUNNER_OS" == "macOS" ]; then | |
| brew install gcc meson ninja openblas netcdf hdf5 | |
| # Link gfortran | |
| for gfortran_bin in /opt/homebrew/bin/gfortran-* /usr/local/bin/gfortran-*; do | |
| if [ -f "$gfortran_bin" ]; then | |
| sudo ln -sf "$gfortran_bin" /usr/local/bin/gfortran && break | |
| fi | |
| done | |
| fi | |
| pip install meson | |
| - name: Build wheels | |
| run: python -m cibuildwheel --output-dir wheelhouse quippy | |
| env: | |
| # For Linux matrix entries, build only specific Python versions | |
| # For macOS, build all supported versions (3.9+) | |
| CIBW_BUILD: ${{ matrix.cibw_build || 'cp39-* cp310-* cp311-* cp312-* cp313-*' }} | |
| # Skip PyPy and musllinux | |
| CIBW_SKIP: "pp* *musllinux*" | |
| CIBW_BUILD_VERBOSITY: 1 | |
| # Use matrix-specified manylinux image (manylinux2014 or manylinux_2_28) | |
| CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux_image || 'manylinux2014' }} | |
| # Install system dependencies in build containers | |
| # manylinux2014 uses yum, manylinux_2_28 uses dnf | |
| CIBW_BEFORE_ALL_LINUX: ${{ matrix.before_all || 'yum install -y openblas-devel lapack-devel netcdf-devel hdf5-devel' }} | |
| CIBW_BEFORE_ALL_MACOS: > | |
| brew install openblas netcdf hdf5 || true | |
| # Build QUIP libraries inside each wheel's isolated environment | |
| # Install meson/ninja in the current Python environment, then build QUIP | |
| CIBW_BEFORE_BUILD_LINUX: > | |
| pip install meson ninja && | |
| cd {package} && cd .. && | |
| meson setup builddir && | |
| meson compile -C builddir | |
| CIBW_BEFORE_BUILD_MACOS: > | |
| pip install meson ninja && | |
| cd {package} && cd .. && | |
| PKG_CONFIG_PATH="/opt/homebrew/opt/openblas/lib/pkgconfig:/usr/local/opt/openblas/lib/pkgconfig" meson setup builddir && | |
| meson compile -C builddir | |
| # Set environment variables for builds | |
| # Linux: Set PKG_CONFIG_PATH and LD_LIBRARY_PATH for auditwheel to find QUIP libraries | |
| CIBW_ENVIRONMENT_LINUX: > | |
| PKG_CONFIG_PATH="/usr/lib64/pkgconfig:/usr/local/lib64/pkgconfig" | |
| LD_LIBRARY_PATH="/project/builddir/src/libAtoms:/project/builddir/src/fox:/project/builddir/src/GAP:/project/builddir/src/Potentials:/project/builddir/src/Utils:/project/builddir/src/Programs:$LD_LIBRARY_PATH" | |
| # macOS: Pass through GITHUB_WORKSPACE and set library paths | |
| # Set MACOSX_DEPLOYMENT_TARGET to match the runner's Homebrew libraries | |
| CIBW_ENVIRONMENT_PASS_MACOS: "GITHUB_WORKSPACE" | |
| CIBW_ENVIRONMENT_MACOS: > | |
| PATH="/opt/homebrew/bin:/usr/local/bin:$PATH" | |
| PKG_CONFIG_PATH="/opt/homebrew/opt/openblas/lib/pkgconfig:/usr/local/opt/openblas/lib/pkgconfig" | |
| MACOSX_DEPLOYMENT_TARGET="${{ steps.arch.outputs.macos_target }}" | |
| QUIP_LIB_PATH="${GITHUB_WORKSPACE}/builddir/src/libAtoms:${GITHUB_WORKSPACE}/builddir/src/fox:${GITHUB_WORKSPACE}/builddir/src/GAP:${GITHUB_WORKSPACE}/builddir/src/Potentials:${GITHUB_WORKSPACE}/builddir/src/Utils:${GITHUB_WORKSPACE}/builddir/src/Programs" | |
| # macOS: Custom repair command to bundle QUIP libraries into wheel | |
| # Find GCC lib path via brew, set DYLD_LIBRARY_PATH for delocate to find all libs | |
| CIBW_REPAIR_WHEEL_COMMAND_MACOS: > | |
| GCC_LIB="$(brew --prefix gcc)/lib/gcc/current" && | |
| DYLD_LIBRARY_PATH="${GCC_LIB}:${QUIP_LIB_PATH}" | |
| delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel} | |
| # Build with meson-python (already configured in pyproject.toml) | |
| CIBW_BUILD_FRONTEND: "build" | |
| # Architecture setting | |
| CIBW_ARCHS: ${{ steps.arch.outputs.arch }} | |
| # Test that the wheel works correctly | |
| # Note: Don't run executables as they may hang on Linux waiting for input | |
| CIBW_TEST_COMMAND: > | |
| python -c "import quippy" && | |
| python -c "import os, quippy; assert os.path.exists(os.path.join(quippy.__path__[0], 'quip')), 'quip executable missing'" && | |
| python -c "import os, quippy; assert os.path.exists(os.path.join(quippy.__path__[0], 'gap_fit')), 'gap_fit executable missing'" && | |
| python -c "import os, quippy; assert os.path.exists(os.path.join(quippy.__path__[0], 'md')), 'md executable missing'" | |
| - name: Verify wheel contents | |
| run: | | |
| echo "=== Checking wheel contents for executables ===" | |
| for whl in wheelhouse/*.whl; do | |
| echo "" | |
| echo "=== Contents of $whl ===" | |
| unzip -l "$whl" | grep -E "(quip|gap_fit|md)$" || echo "WARNING: No executables found in $whl" | |
| done | |
| - name: Debug - list environment | |
| if: failure() | |
| run: | | |
| echo "=== Environment ===" | |
| env | sort | |
| echo "=== Python info ===" | |
| python --version | |
| pip list | |
| # Uncomment to get SSH access for testing | |
| # - name: Setup tmate session | |
| # if: failure() | |
| # uses: mxschmitt/action-tmate@v3 | |
| # timeout-minutes: 15 | |
| - name: Upload wheels as artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: wheels-${{ matrix.name }} | |
| path: ./wheelhouse/*.whl | |
| # Combine all wheels and create release | |
| release: | |
| name: Create release | |
| needs: build_wheels | |
| runs-on: ubuntu-latest | |
| if: startsWith(github.ref, 'refs/tags/') | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download all wheel artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: wheels-* | |
| merge-multiple: true | |
| path: wheelhouse | |
| - name: Build source tarball | |
| run: | | |
| pip install git-archive-all | |
| version=$(echo ${{ github.ref }} | sed -e 's|refs/tags/||') | |
| git-archive-all QUIP-$version.tar.gz | |
| - name: Release wheels and source tarball | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: | | |
| wheelhouse/*.whl | |
| QUIP-*.tar.gz | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Check if production release tag | |
| id: check-tag | |
| run: | | |
| if [[ ${{ github.ref }} =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| echo "match=true" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Deploy to PyPI | |
| if: steps.check-tag.outputs.match == 'true' | |
| run: | | |
| pip install twine | |
| twine upload wheelhouse/*.whl | |
| env: | |
| TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} | |
| TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} |