From a10077a7d6f6fa00c319ada45e0877b4bfb0fdad Mon Sep 17 00:00:00 2001 From: Fernando Date: Tue, 23 Jun 2026 16:10:40 -0400 Subject: [PATCH 1/5] =?UTF-8?q?ci:=20bust=20stale=20macOS=20OGRE=20cache?= =?UTF-8?q?=20(xcode263)=20=E2=80=94=20unblock=20the=20macOS=20deploy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 3.9.1 release deploy failed on build-macos: No rule to make target '.../Xcode_26.5/.../libz.tbd', needed by QtMeshEditor The Pin-Xcode step selects Xcode 26.3 consistently on all macOS jobs, but the OGRE cache under key 'xcode26b' was built earlier under Xcode 26.5 and its CMake export hardcodes 26.5's libz.tbd path. Restoring it into a 26.3 build breaks the link. Bump MACOS_CACHE_VERSION xcode26b → xcode263 so OGRE/Assimp rebuild under the pinned 26.3 and the stale cache is discarded. (Windows + Linux .deb artifacts already published for 3.9.1; this lets the macOS artifact + Homebrew cask update complete on a deploy re-run.) Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/deploy.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c2c918c61..4b2492a1f 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -23,11 +23,14 @@ env: ASSIMP_DIR_VERSION: '6.0' OGRE_VERSION: '14.5.2' # Bump to bust the macOS assimp/ogre caches. The cached OGRE/Assimp SDKs bake - # absolute Xcode SDK paths (e.g. .../usr/lib/libz.tbd) into their CMake export; - # when the macos-latest runner image bumps Xcode, a stale cache hit makes - # build-macos fail with "No rule to make target '/libz.tbd'". Bump - # this whenever the runner's Xcode/SDK changes. - MACOS_CACHE_VERSION: 'xcode26b' + # an absolute Xcode SDK path (e.g. .../usr/lib/libz.tbd) into their CMake + # export. The Pin-Xcode step below selects a CONSISTENT Xcode across all macOS + # jobs (currently 26.3), but a cache built earlier under a different Xcode + # (26.5) still carries that old libz.tbd path and, when restored into a 26.3 + # build, fails with "No rule to make target '.../Xcode_26.5/...libz.tbd'" + # (this broke the 3.9.1 macOS deploy). Bump this whenever the pinned Xcode + # changes so the SDK is rebuilt against it. (xcode263 = under Pin step Xcode 26.3.) + MACOS_CACHE_VERSION: 'xcode263' jobs: # send-slack-notification: From f266c6ba6c98d6d283201f3b90741229ee4a14ef Mon Sep 17 00:00:00 2001 From: Fernando Date: Tue, 23 Jun 2026 16:33:19 -0400 Subject: [PATCH 2/5] ci: self-heal macOS OGRE cache across differing per-job Xcode images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The real cause of the build-macos libz.tbd failure: the producer (build-n-cache-ogre-macos) and consumer (build-macos) run on DIFFERENT runner images whose "newest Xcode" differs — producer resolved Xcode 26.5 and cached OGRE with 26.5's absolute libz.tbd path baked into its CMake export; consumer resolved 26.3 and linked against the missing 26.5 path. Just pinning "newest" or bumping the cache version doesn't help because the two images disagree. Fix (self-healing): - Fold the resolved Xcode app name into XCODE_TAG and append it to all macOS assimp/ogre cache keys + restore-keys, so a job only restores a cache built under its OWN Xcode. - Give build-macos (consumer) the same "check out + build OGRE on cache miss" steps the producer has. When the consumer's Xcode differs from the producer's (cache miss), it rebuilds OGRE under its own SDK instead of failing on a stale libz.tbd path. This makes the macOS build robust regardless of which Xcode each runner image ships. (Bigger than the earlier one-line bump, but that couldn't fix a cross-image Xcode disagreement.) Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/deploy.yml | 68 ++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 4b2492a1f..e97120c6d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1583,6 +1583,16 @@ jobs: echo "Selected Xcode: $DEV" sudo xcode-select -s "$DEV" echo "DEVELOPER_DIR=$DEV" >> "$GITHUB_ENV" + # The per-job runner images can carry DIFFERENT newest Xcodes + # (e.g. producer image has 26.5, consumer image only 26.3). The + # OGRE/Assimp SDKs bake the active SDK's absolute libz.tbd path into + # their CMake export, so a cache built under one Xcode can't be + # linked under another. Fold the resolved Xcode app into the cache + # key so each job only restores a cache built under its OWN Xcode; + # build-macos rebuilds OGRE on a miss (steps below) so a mismatch + # self-heals instead of failing with "No rule to make target + # '.../Xcode_XX/...libz.tbd'". + echo "XCODE_TAG=$(basename "$(dirname "$(dirname "$DEV")")")" >> "$GITHUB_ENV" - name: change folder permissions run: | @@ -1606,9 +1616,9 @@ jobs: /usr/local/lib/libzlibstatic.a #key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('/home/runner/work/QtMeshEditor/QtMeshEditor/assimp') }} # Need to delete manually if needed to rebuild. Until I find a better solution for detecting changes in the assimp repo. - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }} + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}-${{ env.XCODE_TAG }} restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}- + ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}-${{ env.XCODE_TAG }}- - if: steps.cache-assimp-macos.outputs.cache-hit != 'true' name: Check out Assimp repo @@ -1636,6 +1646,16 @@ jobs: echo "Selected Xcode: $DEV" sudo xcode-select -s "$DEV" echo "DEVELOPER_DIR=$DEV" >> "$GITHUB_ENV" + # The per-job runner images can carry DIFFERENT newest Xcodes + # (e.g. producer image has 26.5, consumer image only 26.3). The + # OGRE/Assimp SDKs bake the active SDK's absolute libz.tbd path into + # their CMake export, so a cache built under one Xcode can't be + # linked under another. Fold the resolved Xcode app into the cache + # key so each job only restores a cache built under its OWN Xcode; + # build-macos rebuilds OGRE on a miss (steps below) so a mismatch + # self-heals instead of failing with "No rule to make target + # '.../Xcode_XX/...libz.tbd'". + echo "XCODE_TAG=$(basename "$(dirname "$(dirname "$DEV")")")" >> "$GITHUB_ENV" - name: change folder permissions run: | @@ -1657,9 +1677,9 @@ jobs: /usr/local/lib/pkgconfig/assimp.pc /usr/local/lib/libassimp* /usr/local/lib/libzlibstatic.a - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }} + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}-${{ env.XCODE_TAG }} restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}- + ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}-${{ env.XCODE_TAG }}- - name: Cache Ogre id: cache-ogre-macos @@ -1668,7 +1688,7 @@ jobs: cache-name: cache-ogre-macos with: path: ${{github.workspace}}/ogre/SDK - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }} + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}-${{ env.XCODE_TAG }} - if: steps.cache-ogre-macos.outputs.cache-hit != 'true' name: Check out ogre repo @@ -1701,6 +1721,16 @@ jobs: echo "Selected Xcode: $DEV" sudo xcode-select -s "$DEV" echo "DEVELOPER_DIR=$DEV" >> "$GITHUB_ENV" + # The per-job runner images can carry DIFFERENT newest Xcodes + # (e.g. producer image has 26.5, consumer image only 26.3). The + # OGRE/Assimp SDKs bake the active SDK's absolute libz.tbd path into + # their CMake export, so a cache built under one Xcode can't be + # linked under another. Fold the resolved Xcode app into the cache + # key so each job only restores a cache built under its OWN Xcode; + # build-macos rebuilds OGRE on a miss (steps below) so a mismatch + # self-heals instead of failing with "No rule to make target + # '.../Xcode_XX/...libz.tbd'". + echo "XCODE_TAG=$(basename "$(dirname "$(dirname "$DEV")")")" >> "$GITHUB_ENV" - name: change folder permissions run: | @@ -1755,7 +1785,7 @@ jobs: /usr/local/lib/pkgconfig/assimp.pc /usr/local/lib/libassimp* /usr/local/lib/libzlibstatic.a - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }} + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}-${{ env.XCODE_TAG }} - name: Cache Ogre id: cache-ogre-macos @@ -1764,7 +1794,31 @@ jobs: cache-name: cache-ogre-macos with: path: ${{github.workspace}}/ogre/SDK - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }} + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}-${{ env.XCODE_TAG }} + + # If this runner image's Xcode differs from the one the producer cached + # under, the key above misses. Rebuild OGRE here under THIS job's Xcode so + # the SDK's baked libz.tbd path matches what we link against (self-heals the + # cross-image Xcode mismatch instead of failing on a stale libz.tbd path). + - if: steps.cache-ogre-macos.outputs.cache-hit != 'true' + name: Check out ogre repo (cache miss) + uses: actions/checkout@master + with: + repository: OGRECave/ogre + ref: v${{ env.OGRE_VERSION }} + path: ${{github.workspace}}/ogre + + - if: steps.cache-ogre-macos.outputs.cache-hit != 'true' + name: Build Ogre3D repo (cache miss) + run: | + cd ${{github.workspace}}/ogre/ + sudo cmake -S . -DOGRE_BUILD_PLUGIN_ASSIMP=ON -Dassimp_DIR=/usr/local/lib/cmake/assimp-${{ env.ASSIMP_DIR_VERSION }}/ \ + -DOGRE_BUILD_PLUGIN_DOT_SCENE=ON -DOGRE_BUILD_RENDERSYSTEM_GL=ON -DOGRE_BUILD_RENDERSYSTEM_GL3PLUS=ON \ + -DOGRE_BUILD_RENDERSYSTEM_GLES2=OFF -DOGRE_BUILD_TESTS=OFF -DOGRE_BUILD_TOOLS=OFF -DOGRE_BUILD_SAMPLES=OFF \ + -DOGRE_BUILD_COMPONENT_CSHARP=OFF -DOGRE_BUILD_COMPONENT_JAVA=OFF -DOGRE_BUILD_COMPONENT_PYTHON=OFF \ + -DOGRE_INSTALL_TOOLS=OFF -DOGRE_INSTALL_DOCS=OFF -DOGRE_INSTALL_SAMPLES=OFF -DOGRE_BUILD_LIBS_AS_FRAMEWORKS=OFF \ + -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + sudo make install -j8 - name: Configure CMake env: From 28ab805bdf6ba850a81605dfdae241d03bf480c0 Mon Sep 17 00:00:00 2001 From: Fernando Date: Tue, 23 Jun 2026 16:56:15 -0400 Subject: [PATCH 3/5] ci: keep assimp macOS cache Xcode-agnostic (only ogre is Xcode-keyed) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous commit Xcode-keyed BOTH the assimp and ogre macOS caches. That broke build-macos on a runner whose Xcode differed from the producer's: assimp cache-missed (no assimp-build-on-miss exists) so find_package(assimp) failed with "Could not find a package configuration file provided by assimp". Assimp is a plain static lib that doesn't bake absolute SDK paths, so one assimp cache is valid across Xcode versions — revert XCODE_TAG on the 3 assimp keys, keeping it ONLY on the 2 ogre keys (ogre's CMake export DOES bake an absolute libz.tbd path, which is why ogre needs per-Xcode keying + the consumer's rebuild-on-miss). The shared assimp cache is then always present for the ogre rebuild to link against. Verified on the failing run: Qt + OGRE now resolve and link (no libz.tbd error); this removes the remaining assimp-not-found failure. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/deploy.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e97120c6d..9b45a2148 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1616,9 +1616,12 @@ jobs: /usr/local/lib/libzlibstatic.a #key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('/home/runner/work/QtMeshEditor/QtMeshEditor/assimp') }} # Need to delete manually if needed to rebuild. Until I find a better solution for detecting changes in the assimp repo. - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}-${{ env.XCODE_TAG }} + # NOTE: assimp is NOT Xcode-keyed (unlike ogre): it's a plain static lib + # that doesn't bake absolute SDK paths, so one assimp cache works across + # Xcode versions and stays shared so the ogre-rebuild-on-miss can use it. + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }} restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}-${{ env.XCODE_TAG }}- + ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}- - if: steps.cache-assimp-macos.outputs.cache-hit != 'true' name: Check out Assimp repo @@ -1677,9 +1680,9 @@ jobs: /usr/local/lib/pkgconfig/assimp.pc /usr/local/lib/libassimp* /usr/local/lib/libzlibstatic.a - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}-${{ env.XCODE_TAG }} + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }} restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}-${{ env.XCODE_TAG }}- + ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}- - name: Cache Ogre id: cache-ogre-macos @@ -1785,7 +1788,7 @@ jobs: /usr/local/lib/pkgconfig/assimp.pc /usr/local/lib/libassimp* /usr/local/lib/libzlibstatic.a - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }}-${{ env.XCODE_TAG }} + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.MACOS_CACHE_VERSION }} - name: Cache Ogre id: cache-ogre-macos From 02d10d8a6af75eeadc9a8ae06841dd1e2bd02f62 Mon Sep 17 00:00:00 2001 From: Fernando Date: Tue, 23 Jun 2026 17:50:58 -0400 Subject: [PATCH 4/5] test: fix flaky MainWindowTest.ModeBarLoadsAndModeChange (show window first) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test failed intermittently on CI (Xvfb) with: Value of: window->m_modeBarShell->isHidden() Actual: true Expected: false The fixture constructs MainWindow but never show()s it. QToolBar::isHidden() reflects effective visibility, which is only realized once the parent window is mapped — so under Xvfb the shell reports hidden and the assertion is racy. It hit BOTH this branch and the unrelated CI-only PR #756 (which has no source changes), confirming it's a pre-existing flake, not a regression. Fix: show() the window and processEvents() before the visibility assertion. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/mainwindow_test.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mainwindow_test.cpp b/src/mainwindow_test.cpp index 420dfee97..1f99f5325 100644 --- a/src/mainwindow_test.cpp +++ b/src/mainwindow_test.cpp @@ -282,6 +282,13 @@ TEST_F(MainWindowTest, ModeBarLoadsAndModeChangeUpdatesStatusIndicator) ASSERT_EQ(window->m_modeBar->status(), QQuickWidget::Ready); EXPECT_GE(window->m_modeBar->minimumWidth(), 560); EXPECT_EQ(window->toolBarArea(window->m_modeBarShell), Qt::TopToolBarArea); + // QToolBar::isHidden() reflects effective visibility, which is only + // meaningful once the parent window has been shown. The fixture constructs + // MainWindow without show()ing it, so under Xvfb this assertion was flaky + // (the shell reports hidden until the window is mapped). Show the window and + // drain events so the toolbar's visibility is realized before asserting. + window->show(); + app->processEvents(); EXPECT_FALSE(window->m_modeBarShell->isHidden()); ASSERT_NE(window->m_editModeLabel, nullptr); From ca71059b8bde969414be981308379236be3ccd38 Mon Sep 17 00:00:00 2001 From: Fernando Date: Tue, 23 Jun 2026 18:05:43 -0400 Subject: [PATCH 5/5] ci: pin SDKROOT so CMake ZLIB resolves under the selected Xcode (macOS) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build-macos still failed with the Xcode_26.5 libz.tbd path even after pinning DEVELOPER_DIR=Xcode_26.3 and rebuilding OGRE: CMake's find_package(ZLIB) resolved to the SDK that `xcrun` defaults to (26.5 on these images) rather than the xcode-select'd one, so the OGRE SDK's CMake export baked a 26.5 libz.tbd path that the cache then carried forward. Fix: export SDKROOT (from `xcrun --sdk macosx --show-sdk-path` under the pinned Xcode) in the Pin step, so clang AND CMake resolve system libs under the SAME pinned SDK on every macOS job. Bump MACOS_CACHE_VERSION → sdkpin1 to discard the OGRE caches that still carry the 26.5 path. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/deploy.yml | 68 +++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9b45a2148..6e5f79974 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -30,7 +30,7 @@ env: # build, fails with "No rule to make target '.../Xcode_26.5/...libz.tbd'" # (this broke the 3.9.1 macOS deploy). Bump this whenever the pinned Xcode # changes so the SDK is rebuilt against it. (xcode263 = under Pin step Xcode 26.3.) - MACOS_CACHE_VERSION: 'xcode263' + MACOS_CACHE_VERSION: 'sdkpin1' jobs: # send-slack-notification: @@ -1583,15 +1583,21 @@ jobs: echo "Selected Xcode: $DEV" sudo xcode-select -s "$DEV" echo "DEVELOPER_DIR=$DEV" >> "$GITHUB_ENV" + # Pin SDKROOT too. xcode-select / DEVELOPER_DIR alone don't stop + # CMake's find_package(ZLIB) from resolving to whatever SDK `xcrun` + # defaults to (on these images that was Xcode 26.5 even with 26.3 + # selected), so OGRE's CMake export baked a 26.5 libz.tbd path that + # then failed to link under 26.3. Exporting SDKROOT makes clang AND + # CMake resolve system libs under the SAME pinned SDK everywhere. + SDKROOT_PATH="$(xcrun --sdk macosx --show-sdk-path 2>/dev/null)" + [ -n "$SDKROOT_PATH" ] && echo "SDKROOT=$SDKROOT_PATH" >> "$GITHUB_ENV" + echo "Pinned SDKROOT: $SDKROOT_PATH" # The per-job runner images can carry DIFFERENT newest Xcodes - # (e.g. producer image has 26.5, consumer image only 26.3). The - # OGRE/Assimp SDKs bake the active SDK's absolute libz.tbd path into - # their CMake export, so a cache built under one Xcode can't be - # linked under another. Fold the resolved Xcode app into the cache - # key so each job only restores a cache built under its OWN Xcode; - # build-macos rebuilds OGRE on a miss (steps below) so a mismatch - # self-heals instead of failing with "No rule to make target - # '.../Xcode_XX/...libz.tbd'". + # (e.g. producer image has 26.5, consumer image only 26.3). Fold the + # resolved Xcode app into the cache key so each job only restores a + # cache built under its OWN Xcode; build-macos rebuilds OGRE on a + # miss (steps below) so a mismatch self-heals instead of failing + # with "No rule to make target '.../Xcode_XX/...libz.tbd'". echo "XCODE_TAG=$(basename "$(dirname "$(dirname "$DEV")")")" >> "$GITHUB_ENV" - name: change folder permissions @@ -1649,15 +1655,21 @@ jobs: echo "Selected Xcode: $DEV" sudo xcode-select -s "$DEV" echo "DEVELOPER_DIR=$DEV" >> "$GITHUB_ENV" + # Pin SDKROOT too. xcode-select / DEVELOPER_DIR alone don't stop + # CMake's find_package(ZLIB) from resolving to whatever SDK `xcrun` + # defaults to (on these images that was Xcode 26.5 even with 26.3 + # selected), so OGRE's CMake export baked a 26.5 libz.tbd path that + # then failed to link under 26.3. Exporting SDKROOT makes clang AND + # CMake resolve system libs under the SAME pinned SDK everywhere. + SDKROOT_PATH="$(xcrun --sdk macosx --show-sdk-path 2>/dev/null)" + [ -n "$SDKROOT_PATH" ] && echo "SDKROOT=$SDKROOT_PATH" >> "$GITHUB_ENV" + echo "Pinned SDKROOT: $SDKROOT_PATH" # The per-job runner images can carry DIFFERENT newest Xcodes - # (e.g. producer image has 26.5, consumer image only 26.3). The - # OGRE/Assimp SDKs bake the active SDK's absolute libz.tbd path into - # their CMake export, so a cache built under one Xcode can't be - # linked under another. Fold the resolved Xcode app into the cache - # key so each job only restores a cache built under its OWN Xcode; - # build-macos rebuilds OGRE on a miss (steps below) so a mismatch - # self-heals instead of failing with "No rule to make target - # '.../Xcode_XX/...libz.tbd'". + # (e.g. producer image has 26.5, consumer image only 26.3). Fold the + # resolved Xcode app into the cache key so each job only restores a + # cache built under its OWN Xcode; build-macos rebuilds OGRE on a + # miss (steps below) so a mismatch self-heals instead of failing + # with "No rule to make target '.../Xcode_XX/...libz.tbd'". echo "XCODE_TAG=$(basename "$(dirname "$(dirname "$DEV")")")" >> "$GITHUB_ENV" - name: change folder permissions @@ -1724,15 +1736,21 @@ jobs: echo "Selected Xcode: $DEV" sudo xcode-select -s "$DEV" echo "DEVELOPER_DIR=$DEV" >> "$GITHUB_ENV" + # Pin SDKROOT too. xcode-select / DEVELOPER_DIR alone don't stop + # CMake's find_package(ZLIB) from resolving to whatever SDK `xcrun` + # defaults to (on these images that was Xcode 26.5 even with 26.3 + # selected), so OGRE's CMake export baked a 26.5 libz.tbd path that + # then failed to link under 26.3. Exporting SDKROOT makes clang AND + # CMake resolve system libs under the SAME pinned SDK everywhere. + SDKROOT_PATH="$(xcrun --sdk macosx --show-sdk-path 2>/dev/null)" + [ -n "$SDKROOT_PATH" ] && echo "SDKROOT=$SDKROOT_PATH" >> "$GITHUB_ENV" + echo "Pinned SDKROOT: $SDKROOT_PATH" # The per-job runner images can carry DIFFERENT newest Xcodes - # (e.g. producer image has 26.5, consumer image only 26.3). The - # OGRE/Assimp SDKs bake the active SDK's absolute libz.tbd path into - # their CMake export, so a cache built under one Xcode can't be - # linked under another. Fold the resolved Xcode app into the cache - # key so each job only restores a cache built under its OWN Xcode; - # build-macos rebuilds OGRE on a miss (steps below) so a mismatch - # self-heals instead of failing with "No rule to make target - # '.../Xcode_XX/...libz.tbd'". + # (e.g. producer image has 26.5, consumer image only 26.3). Fold the + # resolved Xcode app into the cache key so each job only restores a + # cache built under its OWN Xcode; build-macos rebuilds OGRE on a + # miss (steps below) so a mismatch self-heals instead of failing + # with "No rule to make target '.../Xcode_XX/...libz.tbd'". echo "XCODE_TAG=$(basename "$(dirname "$(dirname "$DEV")")")" >> "$GITHUB_ENV" - name: change folder permissions