From 3f2b219508dcc87ba175456a20d230e6508dd1d9 Mon Sep 17 00:00:00 2001 From: Paul-Edouard Sarlin <15985472+sarlinpe@users.noreply.github.com> Date: Wed, 3 Jan 2024 09:34:58 +0100 Subject: [PATCH] Build wheels for macOS arm64 (Apple Silicon) (#218) - Install dependencies with VCPKG instead of Homebrew - Reduces the wheel size from 27 MB to 9 MB - Supports macOS >= 10.9 (previously only 12.x) - Builds wheels for arm64 - successfully tested --- .github/workflows/build-new.yml | 38 +++++++++++++++-- package/install-colmap-macos.sh | 74 +++++++++++++++------------------ pyproject.toml | 1 - 3 files changed, 67 insertions(+), 46 deletions(-) diff --git a/.github/workflows/build-new.yml b/.github/workflows/build-new.yml index f3c67697..fc4920ea 100644 --- a/.github/workflows/build-new.yml +++ b/.github/workflows/build-new.yml @@ -12,19 +12,49 @@ on: jobs: build: - name: Build on ${{ matrix.os }} - runs-on: ${{ matrix.os }} + name: Build on ${{ matrix.config.os }} ${{ matrix.config.arch }} + runs-on: ${{ matrix.config.os }} strategy: matrix: - os: [ubuntu-latest, macos-12, macos-13] + config: [ + {os: ubuntu-latest}, + {os: macos-13, arch: x86_64}, + {os: macos-13, arch: arm64}, + ] steps: - uses: actions/checkout@v4 + - name: Set macOS env + if: ${{ startsWith(matrix.config.os, 'macos') }} + run: | + if [[ ${{ matrix.config.arch }} == "x86_64" ]]; then + VCPKG_TARGET_TRIPLET="x64-osx" + elif [[ ${{ matrix.config.arch }} == "arm64" ]]; then + VCPKG_TARGET_TRIPLET="arm64-osx-release" + else + exit 1 + fi + echo "VCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET}" >> "$GITHUB_ENV" + + VCPKG_INSTALLATION_ROOT="/Users/runner/work/vcpkg" + CMAKE_TOOLCHAIN_FILE="${VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" + CMAKE_OSX_ARCHITECTURES=${{ matrix.config.arch }} + echo "VCPKG_INSTALLATION_ROOT=${VCPKG_INSTALLATION_ROOT}" >> "$GITHUB_ENV" + echo "CMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" >> "$GITHUB_ENV" + echo "CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}" >> "$GITHUB_ENV" + + # Fix: cibuildhweel cannot interpolate env variables. + CONFIG_SETTINGS="cmake.define.CMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" + CONFIG_SETTINGS="${CONFIG_SETTINGS} cmake.define.VCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET}" + CONFIG_SETTINGS="${CONFIG_SETTINGS} cmake.define.CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}" + echo "CIBW_CONFIG_SETTINGS_MACOS=${CONFIG_SETTINGS}" >> "$GITHUB_ENV" - name: Build wheels uses: pypa/cibuildwheel@v2.16.2 + env: + CIBW_ARCHS_MACOS: ${{ matrix.config.arch }} - name: Archive wheels uses: actions/upload-artifact@v3 with: - name: pycolmap-${{ matrix.os }} + name: pycolmap-${{ matrix.config.os }}-${{ matrix.config.arch }} path: wheelhouse/pycolmap-*.whl pypi-publish: diff --git a/package/install-colmap-macos.sh b/package/install-colmap-macos.sh index aaff94d5..6119851c 100755 --- a/package/install-colmap-macos.sh +++ b/package/install-colmap-macos.sh @@ -1,8 +1,6 @@ #!/bin/bash set -x -e - CURRDIR=$(pwd) -NUM_LOGICAL_CPUS=$(sysctl -n hw.logicalcpu) # See https://github.com/actions/setup-python/issues/577 find /usr/local/bin -lname '*/Library/Frameworks/Python.framework/*' -delete @@ -15,52 +13,46 @@ brew remove swiftlint brew remove node@18 brew update -brew install \ - git \ - wget \ - cmake \ - eigen \ - freeimage \ +brew install git cmake ninja llvm + +cd ${CURRDIR} +#git clone https://github.com/microsoft/vcpkg ${VCPKG_INSTALLATION_ROOT} +git clone --branch sarlinpe/lapack-osx https://github.com/sarlinpe/vcpkg ${VCPKG_INSTALLATION_ROOT} + +cd ${VCPKG_INSTALLATION_ROOT} +./bootstrap-vcpkg.sh +./vcpkg install --recurse --clean-after-build --triplet=${VCPKG_TARGET_TRIPLET} \ + boost-algorithm \ + boost-filesystem \ + boost-graph \ + boost-heap \ + boost-program-options \ + boost-property-map \ + boost-property-tree \ + boost-regex \ + boost-system \ + ceres[lapack,suitesparse] \ + eigen3 \ flann \ - glog \ - gflags \ + freeimage \ metis \ - suite-sparse \ - ceres-solver \ - glew \ - sqlite3 \ - libomp \ - llvm \ - lz4 - -# Install Boost -mkdir boost && cd boost -BOOST_FILENAME="boost_1_83_0" -wget https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/${BOOST_FILENAME}.tar.gz -tar xzf ${BOOST_FILENAME}.tar.gz -cd ${BOOST_FILENAME} -BOOST_DIR=${CURRDIR}/boost_install -./bootstrap.sh --prefix=${BOOST_DIR} \ - --with-libraries=filesystem,system,program_options,graph,test \ - --without-icu clang-darwin -./b2 -j ${NUM_LOGICAL_CPUS} \ - cxxflags="-fPIC" \ - link=static \ - runtime-link=static \ - variant=release \ - --disable-icu \ - --prefix=${BOOST_DIR} \ - install + gflags \ + glog \ + gtest \ + sqlite3 +./vcpkg integrate install cd ${CURRDIR} git clone https://github.com/colmap/colmap.git cd colmap git checkout c0355417328f3706a30a9265fd52bc7a5aa4cb8c mkdir build && cd build -cmake .. -DGUI_ENABLED=OFF \ +export ARCHFLAGS="-arch ${CIBW_ARCHS_MACOS}" +cmake .. -GNinja -DGUI_ENABLED=OFF \ -DCUDA_ENABLED=OFF \ -DCGAL_ENABLED=OFF \ - -DBoost_USE_STATIC_LIBS=OFF \ - -DBOOSTROOT=${BOOST_DIR} \ - -DBoost_NO_SYSTEM_PATHS=ON -make -j ${NUM_LOGICAL_CPUS} install + -DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN_FILE}" \ + -DVCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET} \ + -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} \ + `if [[ ${CIBW_ARCHS_MACOS} == "arm64" ]]; then echo "-DSIMD_ENABLED=OFF"; fi` +ninja install diff --git a/pyproject.toml b/pyproject.toml index 4467d12d..c55b0067 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,4 +38,3 @@ config-settings = "cmake.define.EIGEN3_INCLUDE_DIRS=eigen" [tool.cibuildwheel.macos] before-all = "./package/install-colmap-macos.sh" -config-settings = { "cmake.define.BOOSTROOT" = "boost_install", "cmake.define.Boost_NO_SYSTEM_PATHS" = "ON" }