ci: widen test-distribution macos-test, rebuild cpr on arm64 only#6138
Open
Fedr wants to merge 14 commits into
Open
ci: widen test-distribution macos-test, rebuild cpr on arm64 only#6138Fedr wants to merge 14 commits into
Fedr wants to merge 14 commits into
Conversation
Verify the macOS .pkg installs on the same image set already used by `macos-pip-test` in pip-build.yml (#6137): - arm64 .pkg: macos-14, macos-15, macos-26 (GitHub-hosted) and macos-arm-build-12 (self-hosted). - x64 .pkg: macos-15-intel, macos-26-intel (GitHub-hosted) and macos-x64-build (self-hosted). Previously the matrix only ran one runner per arch (macos-15-intel and macos-latest), so wheel-test coverage was wider than pkg-test coverage.
This was referenced May 21, 2026
fastmcpp's clang.hpp guarded the
`_LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION 0` override with
`!defined(__apple_build_version__)`, so the workaround only fired under
upstream LLVM clang (brew-llvm18) and not under AppleClang. The x64 .pkg
is built with AppleClang on macos-15-intel; its libMRMcp.dylib therefore
referenced __from_native_exception_pointer, which is absent from
/usr/lib/libc++.1.dylib on Monterey (macos-x64-build / Mac Pro 2013):
dyld: Symbol not found: __ZNSt13exception_ptr31__from_native_exception_pointerEPv
Referenced from: libMRMcp.dylib
Expected in: /usr/lib/libc++.1.dylib
The bumped commit (MeshInspector/fastmcpp#2) drops the
__apple_build_version__ guard so the override also applies under
AppleClang, keeping the helper out of libMRMcp.dylib and restoring
.pkg compatibility with the 12.7 deployment target the rest of the
build already targets.
… fix The previous bump (#6138 commit 653d095) brought in only the clang.hpp guard removal, but fastmcpp's own CMakeLists.txt still gated its target_precompile_headers on `CMAKE_CXX_COMPILER_ID STREQUAL "Clang"`, which excludes AppleClang. So fastmcpp_core (a STATIC library) was still being compiled without the workaround under AppleClang, and its .o files dragged the unguarded `__from_native_exception_pointer` reference into libMRMcp.dylib at link time. Same dyld failure as before. This bump picks up MeshInspector/fastmcpp@ecfe6be, which switches the gate to `MATCHES "^(Apple)?Clang$"` so fastmcpp_core's own translation units also see clang.hpp under AppleClang.
The bundled libcpr.1.dylib's LC_BUILD_VERSION minos was tracking the build host's OS via brew's normal per-host bottle selection. When the arm64 .pkg build landed on a Sequoia 15 self-hosted host, brew pulled the arm64_sequoia bottle whose libc++ references __from_native_exception_pointer -- a symbol absent from /usr/lib/libc++.1.dylib on macOS < 15. The .pkg then failed dyld on every macos-14 test runner. Set HOMEBREW_MACOS_VERSION=14.0 and `brew reinstall cpr` after the normal install_brew_requirements.sh step, so the bundled libcpr is always the macOS 14 bottle (which targets minos=14 and doesn't emit the new symbol). The .pkg's effective cpr floor becomes macOS 14 deterministically, regardless of which self-hosted arm64 host CI picks. HOMEBREW_MACOS_VERSION is an undocumented Homebrew internal. If brew removes it, swap for `--build-from-source` with MACOSX_DEPLOYMENT_TARGET=12.7 (slower but officially supported).
The previous attempt used `HOMEBREW_MACOS_VERSION=14.0` to coax brew into picking the macOS 14 bottle. Current brew ignores it in the bottle selection path -- the CI logs show the env was set but the step still poured arm64_sequoia (minos=15). The bundled libcpr.1.dylib's __from_native_exception_pointer reference then failed to resolve on macos-14 hosts as before. Switch to the officially supported `--build-from-source` path with MACOSX_DEPLOYMENT_TARGET=12.7. The libc++ headers seen by the compiler gate _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION on the deployment target, so under 12.7 the inline std::exception_ptr machinery skips the helper and no reference to it gets emitted into libcpr.dylib. Cost: a few minutes of compile time per build (cpr is small; deps stay as bottles since their dylibs are linked at use sites, not compiled into libcpr).
Latest test-distribution run showed the from-source cpr fixed all four arm64 runners (incl. macos-14) but broke the previously-passing x64 MACPRO2013 test: building cpr from source on a current macos-15-intel host with newer Xcode's libc++ re-introduces the __from_native_exception_pointer reference that the Homebrew CI-built `sonoma` Intel bottle didn't have. On arm64, the situation is reversed -- brew's `arm64_sequoia` bottle has the symbol, but our from-source build doesn't. Gate the rebuild on `runner.arch == 'ARM64'` so: - arm64 hosts use the freshly built libcpr (no symbol) - Intel hosts keep the brew sonoma bottle (no symbol)
Repoint thirdparty/fastmcpp from the now-orphaned PR branch tip ecfe6be to the squash-merge commit c5271bc on fastmcpp's main branch (MeshInspector/fastmcpp#2). Same source content, but the commit is now reachable from main and survives any future garbage collection of the deleted branch.
…ore-macos-runners
oitel
approved these changes
May 22, 2026
| strategy: | ||
| fail-fast: false | ||
| # Matches the GitHub-hosted + self-hosted macOS coverage used by | ||
| # `macos-pip-test` in pip-build.yml (see #6137), so .pkg installs |
Contributor
There was a problem hiding this comment.
Why does it refer a merged PR?
Comment on lines
+146
to
+154
| # arm64 only: brew ships an `arm64_sequoia` cpr bottle (minos=15) that | ||
| # references libc++ symbols absent from /usr/lib/libc++.1.dylib on macOS | ||
| # < 15, breaking .pkg loads on macos-14. Compiling from source under a | ||
| # 12.7 deployment target produces a clean libcpr.1.dylib. | ||
| # x86_64 keeps the brew `sonoma` cpr bottle (the only Intel bottle | ||
| # Homebrew ships) -- it was built on an older Xcode whose libc++ doesn't | ||
| # emit the troublesome reference, so it loads on macos-12+ as-is. A | ||
| # from-source rebuild on a current macos-15-intel runner would | ||
| # *re*introduce the symbol via newer Xcode's libc++. |
Contributor
There was a problem hiding this comment.
Update the comment to indicate the possible problems with Xcode 16+ and libc++.
7 tasks
The arm64 cpr from-source rebuild successfully drops LC_BUILD_VERSION minos to 12.7 but doesn't suppress the inline libc++ references to __from_native_exception_pointer, because Apple's libc++ keys symbol emission on a feature-test macro the deployment target alone doesn't flip. The macro is `_LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION` and the fastmcpp clang.hpp workaround forces it to 0 before <exception> is parsed. This experiment tries to push the same define into cpr's compile via brew's env, attempting four candidate carriers (CXXFLAGS, CPPFLAGS, HOMEBREW_CFLAGS, HOMEBREW_CXXFLAGS) and grepping the build log for the define landing on an actual compiler invocation. The step prints a clear DEFINE REACHED THE COMPILER / STRIPPED line so the next iteration can pick option B (brew tap with patched formula) or option C (build cpr in MeshLib's own source tree) on a confirmed signal. The grep is also a backstop -- even if the dyld test on macos-14 passes by coincidence, an absent define in the log means the workaround is not actually in effect and we'd be back to coin-flipping build hosts.
Fedr
added a commit
that referenced
this pull request
May 22, 2026
…6148) Two coordinated changes, both Intel-side; arm64 build and test configuration stays exactly as in master. 1. macos-test matrix gains two x64 rows alongside the existing macos-15-intel: - macos-26-intel (GitHub-hosted, newer) - macos-x64-build (self-hosted, MACPRO2013 / Monterey 12) The arm64 row stays at the single `macos-latest` runner. 2. thirdparty/fastmcpp bumped to c5271bc (MeshInspector/fastmcpp#2), which widens fastmcpp's libc++ `_LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION 0` workaround to also fire under AppleClang. Without this, libMRMcp.dylib (built with AppleClang for the x64 .pkg) references `__from_native_exception_pointer`, which is absent from /usr/lib/libc++.1.dylib on Monterey 12 and aborts MeshViewer on macos-x64-build at load time. Sibling arm64-side changes from #6138 (additional arm64 test runners and the arm64-scoped cpr from-source rebuild) are intentionally not included here -- arm64 self-hosted build hosts run an older Xcode and the matter is intertwined with brew bottle SDK churn that's worth landing separately.
…ore-macos-runners # Conflicts: # .github/workflows/test-distribution.yml
Option A confirmed that brew's superenv scrubs CXXFLAGS/CPPFLAGS/
HOMEBREW_C{,XX}FLAGS before reaching the formula's compile commands,
so we cannot push -D_LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION=0
via step env. The formula DSL's `ENV.append "CXXFLAGS", ...` does
survive superenv -- it appends to the curated value from inside the
formula. Use that escape hatch via a private tap:
1. `brew tap-new --no-git local/patched` creates a fresh tap (idempotent).
2. `brew cat cpr` prints the canonical homebrew/core formula text.
3. awk inserts the `ENV.append` line right after `def install`.
4. Write the patched formula into the tap as `cpr.rb`.
5. Uninstall the bottle-installed cpr so the keg path frees up.
6. `brew install --build-from-source local/patched/cpr` builds the
patched variant; brew exposes it at $BREW_PREFIX/opt/cpr/ just
like the original, so macos_bundle_dylibs.py finds it without
any further plumbing.
The verification step greps the build log for the define landing on
an actual compiler invocation and `exit 1`s otherwise -- if the
formula DSL ever stops honoring ENV.append we'll see a clean negative
signal instead of another silent coin-flip green.
The strict `/^ def install$/` anchor failed to match on
MacBook-Pro-Daniil's `brew cat cpr` output. Two refinements:
- Drop the `^` and `$` anchors and use a `!done` guard so we still
inject exactly once. Tolerates differing indentation, trailing
whitespace, or line-ending quirks between brew's API-cached
formula and homebrew/core's source.
- On miss, `cat -A` the first 60 lines of brew cat output so the
next iteration sees the literal bytes brew is feeding us (control
chars, trailing $, etc.) instead of having to guess again.
Two fixes after option B v2 failed on MacBook-Pro-Daniil: 1. `cat -A` is a GNU extension; BSD cat (the macOS default) only has `cat -v` for similar control-char visualisation. Replace. 2. Use `brew formula cpr` (which prints the path of the formula .rb file on disk) and read the file directly with awk, instead of piping `brew cat cpr`. On hosts running brew in API mode the `brew cat` command can produce a stripped or JSON-derived variant without the literal `def install` line; the on-disk file is the canonical Ruby source either way. If both still miss, the diagnostic dumps the first 60 lines of each input through `cat -v` so we can see whether the formula was empty, encoded oddly, or simply different from upstream.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings
test-distribution / macos-testup to parity withmacos-pip-test(#6137) and fixes the dyld-symbol-mismatch failures the wider matrix surfaced on older macOS runners.Three coordinated changes:
1.
macos-testmatrix expansion (.github/workflows/test-distribution.yml)Matches the 7-runner image set already used by
macos-pip-test:macos-14,macos-15,macos-26(GitHub-hosted) +macos-arm-build-12(self-hosted)macos-15-intel,macos-26-intel(GitHub-hosted) +macos-x64-build(self-hosted)Before this PR the matrix had a single GitHub-hosted runner per arch, so the .pkg distributables were never exercised on macos-14/15/26 even though the wheels were.
2. fastmcpp submodule bump
thirdparty/fastmcpp→ fastmcppc5271bc(MeshInspector/fastmcpp#2 merged into main). That PR widens the_LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION 0workaround to also fire under AppleClang (both at the#ifinclang.hppand at theCMAKE_CXX_COMPILER_IDgate in CMakeLists.txt). Without this,libMRMcp.dylibshipped a reference to__from_native_exception_pointer— absent from/usr/lib/libc++.1.dylibon macOS 12 — and the x64 .pkg refused to load onmacos-x64-build(Mac Pro 2013 / Monterey).3. arm64-only cpr from-source rebuild (
.github/actions/install-macos-thirdparty/action.yml)Brew's prebuilt
arm64_sequoiacpr bottle (minos=15) references the same__from_native_exception_pointersymbol via libc++ inline code, breaking the arm64 .pkg on macos-14 runners. Compiling cpr from source on the arm64 build host withMACOSX_DEPLOYMENT_TARGET=12.7produces a cleanlibcpr.1.dylib.x86_64 keeps the brew
sonomacpr bottle as-is — that bottle was built by Homebrew CI on an older Xcode whose libc++ doesn't emit the troublesome reference, and a from-source rebuild on a currentmacos-15-intelhost with newer Xcode would actually reintroduce the symbol. Hence the explicitif: runner.arch == 'ARM64'scope on the rebuild step.CI scope
Only macOS distribution testing is affected. Non-mac jobs are disabled via labels.
full-ciis set soupload_artifactsis true andtest-distributionactually runs.Test plan
test-distribution / macos-test(arch, runner) combinations pass:(arm64, macos-14)← canary for the fastmcpp + arm64-only-cpr-rebuild combo(arm64, macos-15)(arm64, macos-26)(arm64, macos-arm-build-12)(x64, macos-15-intel)(x64, macos-26-intel)(x64, macos-x64-build)← canary for the fastmcpp fix (Mac Pro 2013 / Monterey 12)Related