Skip to content

Pin CMAKE_OSX_DEPLOYMENT_TARGET so one build runs on older macOS #2565

Description

@dcwhite

Nothing in the build sets CMAKE_OSX_DEPLOYMENT_TARGET — the only matches in the tree are vendored libxml2's autoconf and an unrelated HTML file. When it is unset, CMake defaults the deployment target to the version of macOS the build happened to run on.

Two consequences:

1. The macOS floor of a release is an accident of the build machine. Whichever runner or laptop cut the build silently becomes the minimum supported version. Nothing declares that floor and nothing checks it.

2. Symbols newer than the floor link cleanly and fail at load time on users' machines. With a pinned deployment target the compiler can diagnose these (-Wunguarded-availability) and the linker can weak-link them. Unpinned, it has no version information to act on, so there is no build-time signal at all — the first sign is a user on an older Mac getting dyld: Symbol not found.

Concrete instance: #2564

quick_exit entered libSystem in macOS 15.0, and the 15 SDK declares it with no availability annotation — gated only on __DARWIN_C_LEVEL/C11, a compile-time feature gate. On a macOS 14.5 host with the 15.2 SDK:

$ cat t.cc
#include <cstdlib>
void boom() { std::quick_exit(1); }

$ clang++ -std=c++17 -c t.cc -o t.o && nm -u t.o
_quick_exit

Compiles clean, no warning, hard reference — and that binary will not load on macOS < 15. Worth noting the trigger is the SDK, not the host: a macOS 14 machine with Xcode 16 installed builds the broken binary, so "it works on my 14 box" proves nothing.

#2564 fixes that one symbol by always taking _Exit on Apple. That is a per-symbol workaround. The next post-floor API that drifts into the codebase reintroduces the same failure with the same absence of any build-time signal. Gating on __MAC_OS_X_VERSION_MIN_REQUIRED does not help either — it reads the deployment target, which follows the build host when unpinned, so it reads 150000 on exactly the builders that emit the bad reference.

Proposal

Set CMAKE_OSX_DEPLOYMENT_TARGET explicitly in the Superbuild and propagate it to every external project, so SCIRun and all of its dependencies build against one declared floor.

Blast radius is wide — it touches every Superbuild dependency — so this is its own PR rather than a rider on #2564.

Open question

What should the floor be? We have users on older Macs, so this wants a deliberate decision rather than whatever the newest runner happens to be. Whatever we pick becomes an enforced, checkable contract instead of a property of whoever ran the build.

Related: #2564, #2537

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions