This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git
The following commit(s) were added to refs/heads/main by this push:
new 16c18be9d fix: x86 architecture missing from universal2 macOS wheel
(#3114)
16c18be9d is described below
commit 16c18be9dec4b20fbb3acd11a54324bd4278c89f
Author: Madhava Jay <[email protected]>
AuthorDate: Thu Jan 8 17:04:36 2026 +1000
fix: x86 architecture missing from universal2 macOS wheel (#3114)
## Why?
macOS wheels produced by the native release workflow are tagged as
universal2
but contain single‑arch binaries, and artifacts from arm64/x86_64 builds
collide. This makes the published mac wheels incorrect.
You can check by doing this:
```
cd pyfory-0.14.1-cp313-cp313-macosx_15_0_universal2.whl ✔
~/Dow/pyfory-0.14.1-cp313-cp313-macosx_15_0_universal2.whl find ./ -name
"mmh3.so"
./pyfory/lib/mmh3/mmh3.so
~/Dow/pyfory-0.14.1-cp313-cp313-macosx_15_0_universal2.whl lipo -archs
./pyfory/lib/mmh3/mmh3.so
arm64
```
This causes it to crash on intel mac.
I tested this in github CI here:
https://github.com/madhavajay/fory/actions/runs/20806248646/job/59761528285
```
Unpacking to: verify/pyfory-0.14.1.dev0...OK
pyfory/_util.so: x86_64 arm64
pyfory/serialization.so: x86_64 arm64
pyfory/format/_format.so: x86_64 arm64
pyfory/lib/mmh3/mmh3.so: x86_64 arm64
```
## What does this PR do?
- Builds macOS wheels separately on arm64 and x86_64 runners, with
explicit
macosx_11_0_<arch> tags.
- Merges the two wheels into a real universal2 wheel using lipo.
- Verifies the merged binaries contain both architectures and that the
wheel
tag is macosx_11_0_universal2.
- Adds PYFORY_WHEEL_PLAT support in ci/deploy.sh to force mac wheel
tags.
## Related issues
N/A
## Does this PR introduce any user-facing change?
No
## Benchmark
N/A (CI/workflow-only change; no runtime impact)
---
.github/workflows/build-native-pr.yml | 146 ++++++++++++++++++++++--
.github/workflows/build-native-release.yml | 173 +++++++++++++++++++++++++++--
ci/deploy.sh | 17 ++-
3 files changed, 313 insertions(+), 23 deletions(-)
diff --git a/.github/workflows/build-native-pr.yml
b/.github/workflows/build-native-pr.yml
index 044c8f077..bdb2fef7b 100644
--- a/.github/workflows/build-native-pr.yml
+++ b/.github/workflows/build-native-pr.yml
@@ -24,11 +24,10 @@ on:
paths: [ci/**, python/**, .github/workflows/**]
jobs:
- build:
- runs-on: ${{ matrix.os }}
+ build-windows:
+ runs-on: windows-latest
strategy:
matrix:
- os: [macos-latest, windows-latest]
python-version: ['3.13']
steps:
- uses: actions/checkout@v5
@@ -44,11 +43,7 @@ jobs:
~/.local/bin/bazel
C:\bazel\bazel.exe
key: bazel-binary-${{ runner.os }}-${{ runner.arch }}-${{
hashFiles('.bazelversion') }}
- - name: Install bazel
- if: runner.os != 'Windows'
- run: ./ci/run_ci.sh install_bazel
- name: Install bazel (Windows)
- if: runner.os == 'Windows'
run: ./ci/run_ci.sh install_bazel_windows
shell: bash
- name: Build wheel
@@ -63,5 +58,140 @@ jobs:
- name: Upload wheels as artifacts
uses: actions/upload-artifact@v4
with:
- name: pyfory-wheels-native-${{ matrix.os }}-${{
matrix.python-version }}
+ name: pyfory-wheels-native-windows-${{ matrix.python-version }}
+ path: dist/*.whl
+
+ build-macos-arm64:
+ runs-on: macos-15
+ strategy:
+ matrix:
+ python-version: ['3.13']
+ steps:
+ - uses: actions/checkout@v5
+ - uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ cache: 'pip'
+ - name: Cache Bazel binary
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/bin/bazel
+ ~/.local/bin/bazel
+ key: bazel-binary-${{ runner.os }}-${{ runner.arch }}-${{
hashFiles('.bazelversion') }}
+ - name: Install bazel
+ run: ./ci/run_ci.sh install_bazel
+ - name: Build wheel
+ run: ./ci/deploy.sh build_pyfory
+ shell: bash
+ env:
+ MACOSX_DEPLOYMENT_TARGET: "11.0"
+ PYFORY_WHEEL_PLAT: macosx_11_0_arm64
+ - name: Install and verify wheel
+ shell: bash
+ run: |
+ python -m pip install --upgrade pip
+ pip install dist/*.whl
+ python -c "import pyfory; print(pyfory.__version__)"
+ - name: Upload wheel artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: pyfory-macos-arm64-wheel-${{ matrix.python-version }}
+ path: dist/*.whl
+
+ build-macos-x86_64:
+ runs-on: macos-15-intel
+ strategy:
+ matrix:
+ python-version: ['3.13']
+ steps:
+ - uses: actions/checkout@v5
+ - uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ cache: 'pip'
+ - name: Cache Bazel binary
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/bin/bazel
+ ~/.local/bin/bazel
+ key: bazel-binary-${{ runner.os }}-${{ runner.arch }}-${{
hashFiles('.bazelversion') }}
+ - name: Install bazel
+ run: ./ci/run_ci.sh install_bazel
+ - name: Build wheel
+ run: ./ci/deploy.sh build_pyfory
+ shell: bash
+ env:
+ MACOSX_DEPLOYMENT_TARGET: "11.0"
+ PYFORY_WHEEL_PLAT: macosx_11_0_x86_64
+ - name: Install and verify wheel
+ shell: bash
+ run: |
+ python -m pip install --upgrade pip
+ pip install dist/*.whl
+ python -c "import pyfory; print(pyfory.__version__)"
+ - name: Upload wheel artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: pyfory-macos-x86_64-wheel-${{ matrix.python-version }}
+ path: dist/*.whl
+
+ merge-macos-universal2:
+ runs-on: macos-15
+ needs: [build-macos-arm64, build-macos-x86_64]
+ strategy:
+ matrix:
+ python-version: ['3.13']
+ steps:
+ - uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install wheel tooling
+ run: python -m pip install --upgrade pip wheel
+ - name: Download arch wheels
+ uses: actions/download-artifact@v5
+ with:
+ pattern: pyfory-macos-*-wheel-${{ matrix.python-version }}
+ path: artifacts
+ merge-multiple: true
+ - name: Build universal2 wheel
+ shell: bash
+ run: |
+ set -euo pipefail
+ mkdir -p unpacked dist
+ ARM_WHL=$(ls artifacts/*arm64*.whl | head -n1)
+ X86_WHL=$(ls artifacts/*x86_64*.whl | head -n1)
+ python -m wheel unpack "$ARM_WHL" -d unpacked/arm64
+ python -m wheel unpack "$X86_WHL" -d unpacked/x86_64
+ ARM_DIR=$(ls -d unpacked/arm64/pyfory-*)
+ X86_DIR=$(ls -d unpacked/x86_64/pyfory-*)
+ UNIVERSAL_DIR="unpacked/pyfory-universal2"
+ cp -R "$ARM_DIR" "$UNIVERSAL_DIR"
+ for so in pyfory/_util.so pyfory/serialization.so
pyfory/format/_format.so pyfory/lib/mmh3/mmh3.so; do
+ lipo -create "$ARM_DIR/$so" "$X86_DIR/$so" -output
"$UNIVERSAL_DIR/$so"
+ done
+ WHEEL_FILE=$(ls "$UNIVERSAL_DIR"/pyfory-*.dist-info/WHEEL)
+ sed -i '' -e 's/macosx_11_0_arm64/macosx_11_0_universal2/g' \
+ -e 's/macosx_11_0_x86_64/macosx_11_0_universal2/g' \
+ "$WHEEL_FILE"
+ python -m wheel pack "$UNIVERSAL_DIR" -d dist
+ - name: Verify universal2 binaries
+ shell: bash
+ run: |
+ set -euo pipefail
+ mkdir -p verify
+ for whl in dist/*.whl; do
+ python -m wheel unpack "$whl" -d verify
+ done
+ VERIFY_DIR=$(ls -d verify/pyfory-*)
+ WHEEL_FILE=$(ls "$VERIFY_DIR"/pyfory-*.dist-info/WHEEL)
+ grep -q "macosx_11_0_universal2" "$WHEEL_FILE"
+ for so in pyfory/_util.so pyfory/serialization.so
pyfory/format/_format.so pyfory/lib/mmh3/mmh3.so; do
+ echo "$so: $(lipo -archs "$VERIFY_DIR/$so")"
+ done
+ - name: Upload universal2 wheel
+ uses: actions/upload-artifact@v4
+ with:
+ name: pyfory-wheels-native-macos-universal2-${{
matrix.python-version }}
path: dist/*.whl
diff --git a/.github/workflows/build-native-release.yml
b/.github/workflows/build-native-release.yml
index 88af14b94..a531f766c 100644
--- a/.github/workflows/build-native-release.yml
+++ b/.github/workflows/build-native-release.yml
@@ -21,11 +21,10 @@ on:
tags: ['v*'] # NO PATH FILTER - critical for releases
jobs:
- build:
- runs-on: ${{ matrix.os }}
+ build-windows:
+ runs-on: windows-latest
strategy:
matrix:
- os: [macos-15-large, macos-latest, windows-latest]
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v5
@@ -45,11 +44,7 @@ jobs:
~/.local/bin/bazel
C:\bazel\bazel.exe
key: bazel-binary-${{ runner.os }}-${{ runner.arch }}-${{
hashFiles('.bazelversion') }}
- - name: Install bazel
- if: runner.os != 'Windows'
- run: ./ci/run_ci.sh install_bazel
- name: Install bazel (Windows)
- if: runner.os == 'Windows'
run: ./ci/run_ci.sh install_bazel_windows
shell: bash
- name: Build wheel
@@ -64,7 +59,6 @@ jobs:
pip install dist/*.whl
INSTALLED_VERSION=$(python -c "import pyfory;
print(pyfory.__version__)")
echo "Installed version: $INSTALLED_VERSION"
- # Verify version matches the tag
EXPECTED_VERSION="${{ github.ref_name }}"
EXPECTED_VERSION=$(DEPLOY_QUIET=1 ci/deploy.sh parse_py_version
$EXPECTED_VERSION | tail -n1)
echo "Expected version: $EXPECTED_VERSION"
@@ -76,5 +70,166 @@ jobs:
- name: Upload wheels as artifacts
uses: actions/upload-artifact@v4
with:
- name: pyfory-wheels-${{ matrix.os }}-${{ matrix.python-version
}}-${{ github.ref_name }}
+ name: pyfory-wheels-windows-${{ matrix.python-version }}-${{
github.ref_name }}
+ path: dist/*.whl
+
+ build-macos-arm64:
+ runs-on: macos-15
+ strategy:
+ matrix:
+ python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
+ steps:
+ - uses: actions/checkout@v5
+ - name: Bump version
+ run: ./ci/deploy.sh bump_py_version "${{ github.ref_name }}"
+ shell: bash
+ - uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ cache: 'pip'
+ - name: Cache Bazel binary
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/bin/bazel
+ ~/.local/bin/bazel
+ key: bazel-binary-${{ runner.os }}-${{ runner.arch }}-${{
hashFiles('.bazelversion') }}
+ - name: Install bazel
+ run: ./ci/run_ci.sh install_bazel
+ - name: Build wheel
+ shell: bash
+ run: ./ci/deploy.sh build_pyfory
+ env:
+ GITHUB_REF_NAME: ${{ github.ref_name }}
+ MACOSX_DEPLOYMENT_TARGET: "11.0"
+ PYFORY_WHEEL_PLAT: macosx_11_0_arm64
+ - name: Install and verify wheel
+ shell: bash
+ run: |
+ python -m pip install --upgrade pip
+ pip install dist/*.whl
+ INSTALLED_VERSION=$(python -c "import pyfory;
print(pyfory.__version__)")
+ echo "Installed version: $INSTALLED_VERSION"
+ EXPECTED_VERSION="${{ github.ref_name }}"
+ EXPECTED_VERSION=$(DEPLOY_QUIET=1 ci/deploy.sh parse_py_version
$EXPECTED_VERSION | tail -n1)
+ echo "Expected version: $EXPECTED_VERSION"
+ if [ "$INSTALLED_VERSION" != "$EXPECTED_VERSION" ]; then
+ echo "Version mismatch: Expected $EXPECTED_VERSION but got
$INSTALLED_VERSION"
+ exit 1
+ fi
+ echo "Version verification successful"
+ - name: Upload wheel artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: pyfory-macos-arm64-wheel-${{ matrix.python-version }}-${{
github.ref_name }}
+ path: dist/*.whl
+
+ build-macos-x86_64:
+ runs-on: macos-15-intel
+ strategy:
+ matrix:
+ python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
+ steps:
+ - uses: actions/checkout@v5
+ - name: Bump version
+ run: ./ci/deploy.sh bump_py_version "${{ github.ref_name }}"
+ shell: bash
+ - uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ cache: 'pip'
+ - name: Cache Bazel binary
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/bin/bazel
+ ~/.local/bin/bazel
+ key: bazel-binary-${{ runner.os }}-${{ runner.arch }}-${{
hashFiles('.bazelversion') }}
+ - name: Install bazel
+ run: ./ci/run_ci.sh install_bazel
+ - name: Build wheel
+ shell: bash
+ run: ./ci/deploy.sh build_pyfory
+ env:
+ GITHUB_REF_NAME: ${{ github.ref_name }}
+ MACOSX_DEPLOYMENT_TARGET: "11.0"
+ PYFORY_WHEEL_PLAT: macosx_11_0_x86_64
+ - name: Install and verify wheel
+ shell: bash
+ run: |
+ python -m pip install --upgrade pip
+ pip install dist/*.whl
+ INSTALLED_VERSION=$(python -c "import pyfory;
print(pyfory.__version__)")
+ echo "Installed version: $INSTALLED_VERSION"
+ EXPECTED_VERSION="${{ github.ref_name }}"
+ EXPECTED_VERSION=$(DEPLOY_QUIET=1 ci/deploy.sh parse_py_version
$EXPECTED_VERSION | tail -n1)
+ echo "Expected version: $EXPECTED_VERSION"
+ if [ "$INSTALLED_VERSION" != "$EXPECTED_VERSION" ]; then
+ echo "Version mismatch: Expected $EXPECTED_VERSION but got
$INSTALLED_VERSION"
+ exit 1
+ fi
+ echo "Version verification successful"
+ - name: Upload wheel artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: pyfory-macos-x86_64-wheel-${{ matrix.python-version }}-${{
github.ref_name }}
+ path: dist/*.whl
+
+ merge-macos-universal2:
+ runs-on: macos-15
+ needs: [build-macos-arm64, build-macos-x86_64]
+ strategy:
+ matrix:
+ python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
+ steps:
+ - uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install wheel tooling
+ run: python -m pip install --upgrade pip wheel
+ - name: Download arch wheels
+ uses: actions/download-artifact@v5
+ with:
+ pattern: pyfory-macos-*-wheel-${{ matrix.python-version }}-${{
github.ref_name }}
+ path: artifacts
+ merge-multiple: true
+ - name: Build universal2 wheel
+ shell: bash
+ run: |
+ set -euo pipefail
+ mkdir -p unpacked dist
+ ARM_WHL=$(ls artifacts/*arm64*.whl | head -n1)
+ X86_WHL=$(ls artifacts/*x86_64*.whl | head -n1)
+ python -m wheel unpack "$ARM_WHL" -d unpacked/arm64
+ python -m wheel unpack "$X86_WHL" -d unpacked/x86_64
+ ARM_DIR=$(ls -d unpacked/arm64/pyfory-*)
+ X86_DIR=$(ls -d unpacked/x86_64/pyfory-*)
+ UNIVERSAL_DIR="unpacked/pyfory-universal2"
+ cp -R "$ARM_DIR" "$UNIVERSAL_DIR"
+ for so in pyfory/_util.so pyfory/serialization.so
pyfory/format/_format.so pyfory/lib/mmh3/mmh3.so; do
+ lipo -create "$ARM_DIR/$so" "$X86_DIR/$so" -output
"$UNIVERSAL_DIR/$so"
+ done
+ WHEEL_FILE=$(ls "$UNIVERSAL_DIR"/pyfory-*.dist-info/WHEEL)
+ sed -i '' -e 's/macosx_11_0_arm64/macosx_11_0_universal2/g' \
+ -e 's/macosx_11_0_x86_64/macosx_11_0_universal2/g' \
+ "$WHEEL_FILE"
+ python -m wheel pack "$UNIVERSAL_DIR" -d dist
+ - name: Verify universal2 binaries
+ shell: bash
+ run: |
+ set -euo pipefail
+ mkdir -p verify
+ for whl in dist/*.whl; do
+ python -m wheel unpack "$whl" -d verify
+ done
+ VERIFY_DIR=$(ls -d verify/pyfory-*)
+ WHEEL_FILE=$(ls "$VERIFY_DIR"/pyfory-*.dist-info/WHEEL)
+ grep -q "macosx_11_0_universal2" "$WHEEL_FILE"
+ for so in pyfory/_util.so pyfory/serialization.so
pyfory/format/_format.so pyfory/lib/mmh3/mmh3.so; do
+ echo "$so: $(lipo -archs "$VERIFY_DIR/$so")"
+ done
+ - name: Upload universal2 wheel
+ uses: actions/upload-artifact@v4
+ with:
+ name: pyfory-wheels-macos-universal2-${{ matrix.python-version
}}-${{ github.ref_name }}
path: dist/*.whl
diff --git a/ci/deploy.sh b/ci/deploy.sh
index be0c38595..fb0123eb1 100755
--- a/ci/deploy.sh
+++ b/ci/deploy.sh
@@ -90,13 +90,18 @@ build_pyfory() {
$PIP_CMD install setuptools -U
if [[ "$OSTYPE" == "darwin"* ]]; then
- MACOS_VERSION=$(sw_vers -productVersion | cut -d. -f1-2)
- echo "MACOS_VERSION: $MACOS_VERSION"
- if [[ "$MACOS_VERSION" == "13"* ]]; then
- export MACOSX_DEPLOYMENT_TARGET=10.13
- $PYTHON_CMD setup.py bdist_wheel --plat-name macosx_10_13_x86_64
--dist-dir="$ROOT/dist"
+ if [ -n "${PYFORY_WHEEL_PLAT:-}" ]; then
+ echo "PYFORY_WHEEL_PLAT: $PYFORY_WHEEL_PLAT"
+ $PYTHON_CMD setup.py bdist_wheel --plat-name "$PYFORY_WHEEL_PLAT"
--dist-dir="$ROOT/dist"
else
- $PYTHON_CMD setup.py bdist_wheel --dist-dir="$ROOT/dist"
+ MACOS_VERSION=$(sw_vers -productVersion | cut -d. -f1-2)
+ echo "MACOS_VERSION: $MACOS_VERSION"
+ if [[ "$MACOS_VERSION" == "13"* ]]; then
+ export MACOSX_DEPLOYMENT_TARGET=10.13
+ $PYTHON_CMD setup.py bdist_wheel --plat-name macosx_10_13_x86_64
--dist-dir="$ROOT/dist"
+ else
+ $PYTHON_CMD setup.py bdist_wheel --dist-dir="$ROOT/dist"
+ fi
fi
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]