Skip to content

Mac ARM wheels #83

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,16 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

# - name: Install tools (macOS)
# if: contains(matrix.os, 'macos')
# # Install coreutils which includes `nproc` used by `make -j` in suitesparse.sh
# #
# # GitHub actions comes with libomp already installed, but for its native arch only. Must build universal one
# # manually so that both x86 and arm builds can be built.
# run: |
# brew install coreutils
# brew install libomp
# sh add_arm_to_libomp_dylib.sh
- name: Install tools (macOS)
if: contains(matrix.os, 'macos')
# Install coreutils which includes `nproc` used by `make -j` in suitesparse.sh
#
# GitHub actions comes with libomp already installed, but for its native arch only. Must build universal one
# manually so that both x86 and arm builds can be built.
run: |
brew install coreutils
brew install libomp
sh add_arm_to_libomp_dylib.sh

- name: Build Wheels
env:
Expand All @@ -92,8 +92,8 @@ jobs:
# Uncomment to only build CPython wheels
# CIBW_BUILD: "cp*"

# macOS: build x86_64 and arm64
#CIBW_ARCHS_MACOS: "x86_64 arm64"
# macOS: build both x86_64 and arm64.
CIBW_ARCHS_MACOS: "x86_64 arm64"

# No 32-bit builds
CIBW_SKIP: "*-win32 *_i686 *musl*"
Expand Down
34 changes: 33 additions & 1 deletion add_arm_to_libomp_dylib.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
#!/bin/sh
# Construct a universal2 version of homebrew's libomp.
#
# Homebrew's libomp works well to patch Apple clang's missing OpenMP support. The problem is a combination of:
# - Brew installs libomp built for x86 *or* ARM, matching the architecture of the machine it is running on.
# - GitHub Actions only has x86 runners as of now. Check back in Q4 2023. https://github.com/github/roadmap/issues/528
# - The linker will select the first found libomp, and if that version does not include the expected architecture then
# linking will fail.
#
# One solution is to build a universal2 version of libomp that includes both architectures. That's what this script
# does. It adds the ARM version of libomp to the x86 version.
#
# This script assumes it is running on x86 with x86 libomp already installed.

if [ "$(arch)" != "x86_64" ] && [ "$(arch)" != "i386" ]; then
echo "Not running on x86 as expected. Running on:"
arch
echo "If the above says arm64 then this hack is no longer necessary. Remove this script from the build."
exit 1;
fi

#mkdir x86lib
mkdir armlib
Expand All @@ -11,8 +30,21 @@ brew fetch --force --bottle-tag=arm64_big_sur libomp
#tar -xzf $(brew --cache --bottle-tag=x86_64_monterey libomp) --strip-components 2 -C x86lib
tar -xzf $(brew --cache --bottle-tag=arm64_big_sur libomp) --strip-components 2 -C armlib

# merge
# ARM and x86 dylibs have different install names due to different brew install directories.
# The x86 install name will be expected so make the ARM install name match.
X86_INSTALL_NAME="$(otool -X -D $(brew --prefix libomp)/lib/libomp.dylib)"
install_name_tool -id "${X86_INSTALL_NAME}" armlib/lib/libomp.dylib
codesign --force -s - armlib/lib/libomp.dylib

# merge the downloaded (arm) libomp with the already installed (x86) libomp to create a universal libomp
lipo armlib/lib/libomp.dylib $(brew --prefix libomp)/lib/libomp.dylib -output libomp.dylib -create

# print contents of universal library for reference
otool -arch all -L libomp.dylib

# replace the x86-only libomp with the newly-created universal one
cp -f libomp.dylib $(brew --prefix libomp)/lib

# clean up
rm libomp.dylib
rm -rf armlib
5 changes: 2 additions & 3 deletions suitesparse.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ if [ -n "${BREW_LIBOMP}" ]; then
cmake_params+=(-DOpenMP_libomp_LIBRARY="omp")
export LDFLAGS="-L$(brew --prefix libomp)/lib"

export CFLAGS="-arch x86_64"
# # build both x86 and ARM
# export CFLAGS="-arch x86_64 -arch arm64"
# build both x86 and ARM
export CFLAGS="-arch x86_64 -arch arm64"
fi

if [ -n "${CMAKE_GNUtoMS}" ]; then
Expand Down