name: CMake-MacOS on: push: branches: - master pull_request: branches: - '**' env: BUILD_TYPE: Release concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: build: name: ${{ matrix.build_name }} runs-on: ${{ matrix.os }} strategy: fail-fast: true matrix: build_name: [macos-sequoia-intel, macos-sequoia-apple-silicon, macos-tahoe-intel, macos-tahoe-apple-silicon] include: - build_name: macos-sequoia-intel os: macos-15-intel extra_cmake_def: '-DBUILD_AS_BUNDLE=ON' - build_name: macos-sequoia-apple-silicon os: macos-15 extra_cmake_def: '-DBUILD_AS_BUNDLE=ON' - build_name: macos-tahoe-intel os: macos-26-intel extra_cmake_def: '-DBUILD_AS_BUNDLE=ON' - build_name: macos-tahoe-apple-silicon os: macos-26 extra_cmake_def: '-DBUILD_AS_BUNDLE=ON' steps: - uses: actions/checkout@v4 - name: Install Brew Dependencies run: | # Update brew and install from Brewfile if present, or specific packages brew install pcl opencv octomap g2o pdal yaml-cpp - name: Resolve dependency versions id: depver # The source dependencies link against these Homebrew libraries and are # compiled with Xcode's toolchain, so both are folded into the source-deps # cache key: a Homebrew bump (e.g. a new Eigen) or an Xcode update # invalidates the cache and forces a rebuild. run: | BREW=$(brew list --versions eigen boost yaml-cpp | sort) XCODE=$(xcodebuild -version 2>/dev/null || clang --version | head -1) HASH=$(printf '%s\n%s\n' "$BREW" "$XCODE" | shasum | cut -d' ' -f1) echo "hash=$HASH" >> "$GITHUB_OUTPUT" - name: Cache Source Dependencies id: cache-src-deps uses: actions/cache@v4 with: # Staged install tree (DESTDIR) of the source-built dependencies. path: ${{ runner.temp }}/deps-stage # Rebuild when the OS image, pinned versions, patches, the linked # Homebrew library versions or the Xcode toolchain change. key: src-deps-${{ matrix.os }}-gtsam4.2.1-libnabo1.1.2-lpm1.4.4-deps${{ steps.depver.outputs.hash }}-${{ hashFiles('.github/patches/*.patch') }} - name: Build Source Dependencies # Dependencies not available (or not in a usable version) from Homebrew are # built from source and staged into the cached directory via DESTDIR. # Patches under .github/patches fix compatibility with the current Homebrew # Eigen/Boost versions. Skipped entirely on a cache hit. if: steps.cache-src-deps.outputs.cache-hit != 'true' run: | set -e NPROC=$(sysctl -n hw.logicalcpu) PATCHES="${{ github.workspace }}/.github/patches" SRC="${{ runner.temp }}/src-deps" STAGE="${{ runner.temp }}/deps-stage" mkdir -p "$SRC" "$STAGE" # --- GTSAM 4.2.1 --- git clone --depth 1 --branch 4.2.1 https://github.com/borglab/gtsam.git "$SRC/gtsam" cd "$SRC/gtsam" git apply "$PATCHES/gtsam-4.2.1-eigen5.patch" cmake -B build \ -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \ -DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF \ -DGTSAM_WITH_TBB=OFF \ -DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF \ -DGTSAM_BUILD_TESTS=OFF \ -DGTSAM_BUILD_UNSTABLE=OFF \ -DGTSAM_USE_SYSTEM_EIGEN=ON \ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 cmake --build build -j$NPROC DESTDIR="$STAGE" cmake --install build # --- libnabo 1.1.2 (required by libpointmatcher) --- git clone --depth 1 --branch 1.1.2 https://github.com/ethz-asl/libnabo.git "$SRC/libnabo" cd "$SRC/libnabo" git apply "$PATCHES/libnabo-1.1.2.patch" cmake -B build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} cmake --build build -j$NPROC DESTDIR="$STAGE" cmake --install build # --- libpointmatcher 1.4.4 (finds libnabo from the staged prefix) --- git clone --depth 1 --branch 1.4.4 https://github.com/ethz-asl/libpointmatcher.git "$SRC/libpointmatcher" cd "$SRC/libpointmatcher" git apply "$PATCHES/libpointmatcher-1.4.4-boost.patch" cmake -B build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_PREFIX_PATH="$STAGE/usr/local" cmake --build build -j$NPROC DESTDIR="$STAGE" cmake --install build - name: Install Source Dependencies # Copy the (possibly cached) staged install tree into /usr/local so # rtabmap's find_package() and the bundle fixup (which search /usr/local) # pick the dependencies up. Runs on both cache hit and miss. run: | set -e STAGE="${{ runner.temp }}/deps-stage" if [ ! -d "$STAGE/usr/local" ]; then echo "No staged dependencies found at $STAGE/usr/local" >&2 exit 1 fi sudo cp -a "$STAGE/usr/local/." /usr/local/ - name: Configure CMake run: | cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} ${{ matrix.extra_cmake_def }} - name: Build run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} - name: Info working-directory: ${{github.workspace}}/build/bin run: | ./rtabmap-console --version - name: Build MacOS Package run: | cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --target package - name: Upload RTABMap Artifacts (DMG) uses: actions/upload-artifact@v4 with: name: RTABMap-Binaries-${{ matrix.build_name }}-nonsigned-zip path: | build/RTABMap-*.dmg compression-level: 0 if-no-files-found: warn retention-days: ${{ github.event_name == 'pull_request' && 1 || 90 }} # - name: Test # working-directory: ${{github.workspace}}/build # # Execute tests defined by the CMake configuration. # # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail # run: ctest -C ${{env.BUILD_TYPE}}