Skip to content

clang.hpp + CMakeLists: apply libc++ workaround under AppleClang too#2

Merged
Fedr merged 2 commits into
mainfrom
apply-libcpp-workaround-to-appleclang
May 22, 2026
Merged

clang.hpp + CMakeLists: apply libc++ workaround under AppleClang too#2
Fedr merged 2 commits into
mainfrom
apply-libcpp-workaround-to-appleclang

Conversation

@Fedr
Copy link
Copy Markdown

@Fedr Fedr commented May 21, 2026

Summary

The clang.hpp workaround for llvm/llvm-project#86077 defines _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION 0 to keep inline libc++ codepaths from emitting references to __from_native_exception_pointer. That symbol was added to libc++ in LLVM 18 / macOS 14 SDK and is absent from /usr/lib/libc++.1.dylib on earlier macOS, so any dylib that references it fails dyld on macOS 12 or 13 hosts.

The original code guarded the override two ways and both excluded AppleClang:

location guard what it excluded
include/fastmcpp/clang.hpp !defined(__apple_build_version__) The whole #undef/#define block was skipped when the consumer compiles with AppleClang — __apple_build_version__ is defined only by AppleClang.
CMakeLists.txt CMAKE_CXX_COMPILER_ID STREQUAL "Clang" The target_precompile_headers call that injects clang.hpp into fastmcpp_core's own translation units never ran on AppleClang — AppleClang's compiler id is "AppleClang".

Both gates have to be lifted in tandem: the consumer-side fix in clang.hpp is moot if fastmcpp_core itself is still compiled without the override, since fastmcpp_core is a STATIC library and its .o files end up linked into downstream dylibs.

Apple's libc++ derives from upstream LLVM and honors the same macro, so the override is meaningful under AppleClang. On older AppleClang whose libc++ doesn't define the macro at all, the #undef/#define pair is a harmless no-op.

Concrete downstream symptom

MeshInspector/MeshLib PR #6138, x64 .pkg built with AppleClang on macos-15-intel, installed on a Mac Pro 2013 running macOS 12:

dyld: Symbol not found: __ZNSt13exception_ptr31__from_native_exception_pointerEPv
  Referenced from: .../libMRMcp.dylib
  Expected in:     /usr/lib/libc++.1.dylib

libMRMcp.dylib is a MeshLib library that statically links fastmcpp_core. With this PR applied (consumer side via submodule bump), the reference is no longer emitted under AppleClang and the .pkg loads cleanly on macOS 12/13 hosts.

Test plan

  • fastmcpp's existing CI passes (no regression on the build configs it covers).
  • Downstream: MeshLib PR #6138 with thirdparty/fastmcpp pointed at this PR's commit sees test-distribution / macos-test (x64, macos-x64-build, *x64.pkg) reach "Run MeshViewer" without a __from_native_exception_pointer dyld abort.

Fedr added a commit to MeshInspector/MeshLib that referenced this pull request 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.
@Fedr Fedr changed the title clang.hpp: apply libc++ __init_primary_exception override to AppleClang too clang.hpp + CMakeLists: apply libc++ workaround under AppleClang too May 21, 2026
The clang.hpp workaround for llvm/llvm-project#86077
defines `_LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION 0` to keep
inline libc++ codepaths from emitting references to
`__from_native_exception_pointer`. That symbol was added to libc++ in
LLVM 18 / macOS 14 SDK and is absent from /usr/lib/libc++.1.dylib on
earlier macOS, so any dylib that references it fails dyld on macos-12
or macos-13 hosts. The original code guarded the override two ways and
both excluded AppleClang:

  - clang.hpp:  `!defined(__apple_build_version__)` skipped the entire
                #undef/#define when the consumer compiles with
                AppleClang (the macro is defined only by AppleClang).
  - CMakeLists: `CMAKE_CXX_COMPILER_ID STREQUAL "Clang"` matched only
                upstream LLVM clang -- AppleClang's compiler id is
                `"AppleClang"`, so the target_precompile_headers call
                that injects clang.hpp into fastmcpp_core's own
                translation units never ran on AppleClang.

Apple's libc++ derives from upstream and honors the same macro, so the
override is meaningful under AppleClang. On older AppleClang whose
libc++ doesn't define the macro at all, the #undef/#define is a
harmless no-op.

Both gates have to be lifted in tandem: the consumer-side fix in
clang.hpp is moot if fastmcpp_core itself is still compiled without the
override, since `fastmcpp_core` is a STATIC library and its .o files
get linked into downstream dylibs at the consumer site.

Concrete downstream symptom (MeshInspector/MeshLib PR #6138, x64 .pkg
built with AppleClang on macos-15-intel, installed on a Mac Pro 2013
running macOS 12):

    dyld: Symbol not found: __ZNSt13exception_ptr31__from_native_exception_pointerEPv
      Referenced from: .../libMRMcp.dylib
      Expected in:     /usr/lib/libc++.1.dylib
@Fedr Fedr force-pushed the apply-libcpp-workaround-to-appleclang branch from ecfe6be to 34f95a3 Compare May 22, 2026 09:37
Comment thread CMakeLists.txt Outdated

# inject work-around for Clang libc++ and older Xcode versions' compatibility
if(APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "^(Apple)?Clang$")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make it more readable by replacing MATCHES with two STREQUAL's.

Review nit -- two explicit equality checks are easier to read than the
regex, and the gate has only two compiler ids to cover.
@Fedr Fedr merged commit c5271bc into main May 22, 2026
@Fedr Fedr deleted the apply-libcpp-workaround-to-appleclang branch May 22, 2026 11:46
Fedr added a commit to MeshInspector/MeshLib that referenced this pull request May 22, 2026
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants