Problem
The native CI mutation probe (scripts/test-native-cmake.py --mutations) proves a STATIC-linked C/C++ consumer fails to build when a required symbol (axiolid_v0_4_version) is removed from main.c/main.cpp. This passes on ubuntu-22.04 / STATIC, but on macos-15-intel and windows-2022 (both Debug/STATIC and Release/STATIC) the mutated consumer builds successfully instead of failing:
native CMake test failed: mutated consumer unexpectedly built: consumer
Where
Hypothesis (unverified — no macOS/Windows toolchain access from this session)
Linking behavior likely differs by platform:
- On ELF/GNU-ld (Linux), an unresolved symbol reference from the consumer's
.o against a static archive is a hard link error by default.
- On Mach-O (macOS
ld/ld64) and MSVC (link.exe), depending on how Axiolid::axiolid_static's INTERFACE_LINK_LIBRARIES and default linker flags are set up, dead-symbol/weak-symbol resolution or two-level namespace lookup rules may allow the link to succeed even with a missing definition — or the consumer object is being compiled/linked against a stale cached artifact from a previous mutation stage in the same CI job.
Suggested investigation (needs actual macOS/Windows runners)
- Reproduce locally on macOS/Windows and inspect the actual linker invocation (
--verbose//VERBOSE) for the mutated-symbol consumer build.
- Check whether
expect_consumer_failure's CMake build dir is being reused/cached across mutation stages (work / "mutation-symbol-build" etc. — verify these are genuinely fresh per-mutation directories, not accidentally reusing object files from the prior successful configure_build_test pass).
- Confirm whether macOS's two-level namespace / lazy symbol binding is masking the missing symbol until runtime rather than link time, and if so, whether
-Wl,-undefined,error (or equivalent MSVC flag) needs to be added to the consumer's or archive's link flags to force eager resolution.
Impact
Downstream STATIC consumers on macOS and Windows are not actually proven to require the declared C ABI symbols by CI — the mutation gate that is supposed to catch a broken/incompatible native package silently passes on these two platforms. SHARED-linkage mutation coverage is unaffected (not investigated in this report, but worth re-checking as a follow-up if SHARED ever shows the same gap).
Related: v0.4 downstream integration (issues #52-#55), CI hardening commit a05cd23.
Problem
The native CI mutation probe (
scripts/test-native-cmake.py --mutations) proves a STATIC-linked C/C++ consumer fails to build when a required symbol (axiolid_v0_4_version) is removed frommain.c/main.cpp. This passes onubuntu-22.04 / STATIC, but onmacos-15-intelandwindows-2022(bothDebug/STATICandRelease/STATIC) the mutated consumer builds successfully instead of failing:Where
scripts/test-native-cmake.py::assert_package_mutations/expect_consumer_failure.github/workflows/native.yml, jobsmacos-15-intel / * / STATICandwindows-2022 / * / STATICa05cd23) and earlier run https://github.com/axiolid/kernel/actions/runs/33770220687Hypothesis (unverified — no macOS/Windows toolchain access from this session)
Linking behavior likely differs by platform:
.oagainst a static archive is a hard link error by default.ld/ld64) and MSVC (link.exe), depending on howAxiolid::axiolid_static'sINTERFACE_LINK_LIBRARIESand default linker flags are set up, dead-symbol/weak-symbol resolution or two-level namespace lookup rules may allow the link to succeed even with a missing definition — or the consumer object is being compiled/linked against a stale cached artifact from a previous mutation stage in the same CI job.Suggested investigation (needs actual macOS/Windows runners)
--verbose//VERBOSE) for the mutated-symbol consumer build.expect_consumer_failure's CMake build dir is being reused/cached across mutation stages (work / "mutation-symbol-build"etc. — verify these are genuinely fresh per-mutation directories, not accidentally reusing object files from the prior successfulconfigure_build_testpass).-Wl,-undefined,error(or equivalent MSVC flag) needs to be added to the consumer's or archive's link flags to force eager resolution.Impact
Downstream STATIC consumers on macOS and Windows are not actually proven to require the declared C ABI symbols by CI — the mutation gate that is supposed to catch a broken/incompatible native package silently passes on these two platforms. SHARED-linkage mutation coverage is unaffected (not investigated in this report, but worth re-checking as a follow-up if SHARED ever shows the same gap).
Related: v0.4 downstream integration (issues #52-#55), CI hardening commit a05cd23.