Summary
The native-gcc host preset (cmake --workflow --preset on-host-native-gcc) does not complete on macOS (Apple Silicon, recent Command Line Tools / SDK). It fails in several independent layers — the first masks the rest, so they surface one at a time as each is worked around. The native-clang host path is unaffected. All findings are against main (commit c66a0d2).
1. Toolchain search picks a GCC too old for the current macOS SDK
build-support/lib/cmake/native-gcc.cmake searches gcc-13 first:
find_program(CMAKE_C_COMPILER REQUIRED NAMES gcc-13 gcc-14 gcc-15 gcc ...)
find_program(CMAKE_CXX_COMPILER REQUIRED NAMES g++-13 g++-14 g++-15 g++ ...)
Homebrew gcc-13 (and gcc-14) cannot parse the current macOS SDK headers. Compiling anything that includes <mach/mach.h> (e.g. via googletest's gtest-port.cc) fails with:
.../MacOSX*.sdk/usr/include/mach/message.h:299:1: error: expected constructor, destructor, or type conversion before '(' token
299 | xnu_static_assert_struct_size(mach_msg_type_descriptor_t, 12);
The xnu_static_assert_struct_size macros in mach/port.h are gated on #if __arm64__; the older GCCs don't handle them for this SDK. gcc-16 parses the SDK cleanly. Searching newest-first (gcc-16 … gcc-13) resolves this.
2. With GCC 16, -Os fails to link std::string's move constructor
The MinSizeDebug build type compiles the host build at -Os. Homebrew GCC 16 at -Os emits an undefined reference to the unified C4 constructor variant of the extern-template std::__cxx11::basic_string, which the shipped libstdc++ exports only as C1/C2 (static libstdc++ lacks C4 too). Test executables then fail to link:
Undefined symbols for architecture arm64:
"std::__cxx11::basic_string<...>::basic_string(std::__cxx11::basic_string<...>&&)", referenced from:
__static_initialization_and_destruction_0() in <tu>.o
... in libgtest.a / Catch2 objects
Minimal reproducer (Homebrew g++-16, macOS arm64):
#include <string>
std::string mk(std::string&& s){ return std::string(std::move(s)); }
int main(){ std::string a="x"; return (int)mk(std::move(a)).size(); }
g++-16 -Os … → link fails (undefined ...basic_stringIcSt11char_traitsIcESaIcEEC4EOS4_)
g++-16 -O0 … / g++-16 -O2 … → links (move ctor is inlined, no C4 reference)
The host test build has no size constraint, so building it at -O2 sidesteps the miscompile and is arguably more appropriate for host unit tests anyway.
3. --start-group/--end-group is enabled for GNU on macOS, where Apple ld rejects it
CMakeLists.txt (lines ~18–24):
if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11)
OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_SYSTEM_NAME STREQUAL "Linux"))
set(CMAKE_CXX_LINK_GROUP_USING_RESCAN_SUPPORTED TRUE)
set(CMAKE_CXX_LINK_GROUP_USING_RESCAN "LINKER:--start-group" "LINKER:--end-group")
The Clang branch is correctly restricted to Linux, but the GNU branch has no platform guard. Homebrew GCC on macOS drives Apple's ld, which does not support the GNU archive-group flags:
ld: unknown options: --start-group --end-group
(Clang on macOS avoids this only because its branch requires Linux.) Adding AND NOT APPLE to the GNU branch fixes it; the bare-metal arm-none-eabi cross build is GNU with CMAKE_SYSTEM_NAME=Generic (not APPLE), so it keeps the group flags its GNU ld needs.
4. -Werror=uninitialized in CortexProcessor::GetRevision()
modules/jarnax/source/CortexProcessor.cpp (~line 68):
cortex::Revision CortexProcessor::GetRevision() const {
cortex::Revision revision; // <-- not initialized on all paths GCC can see
if constexpr (cortex::run_in_privileged_mode_only) {
revision = cortex::processor::GetRevision();
} else {
// filled in via the supervisor marshal call by &revision
...
}
return revision;
}
Under GCC, -Werror=uninitialized fires (the supervisor path writes revision through a pointer that GCC can't see through). The sibling GetPartNumber() initializes its local (partno = cortex::PartNumber::Unknown); GetRevision() should likewise value-initialize (cortex::Revision revision{};). Clang does not diagnose this.
Suggested fixes
native-gcc.cmake: search newest GCC first (gcc-16 gcc-15 gcc-14 gcc-13 gcc).
native-gcc.cmake: build the host at -O2 (host tests are not size-constrained), avoiding the GCC-16 -Os std::string C4 link failure.
CMakeLists.txt: add AND NOT APPLE to the GNU branch of the RESCAN link-group check.
CortexProcessor.cpp: value-initialize cortex::Revision revision{};.
Environment
- macOS on Apple Silicon (arm64), recent SDK (the
xnu_static_assert_struct_size macros).
- Homebrew
gcc@13, gcc@14, gcc@16 installed.
- Reference: the
native-clang host preset builds and tests cleanly.
Summary
The
native-gcchost preset (cmake --workflow --preset on-host-native-gcc) does not complete on macOS (Apple Silicon, recent Command Line Tools / SDK). It fails in several independent layers — the first masks the rest, so they surface one at a time as each is worked around. Thenative-clanghost path is unaffected. All findings are againstmain(commitc66a0d2).1. Toolchain search picks a GCC too old for the current macOS SDK
build-support/lib/cmake/native-gcc.cmakesearchesgcc-13first:Homebrew
gcc-13(andgcc-14) cannot parse the current macOS SDK headers. Compiling anything that includes<mach/mach.h>(e.g. via googletest'sgtest-port.cc) fails with:The
xnu_static_assert_struct_sizemacros inmach/port.hare gated on#if __arm64__; the older GCCs don't handle them for this SDK.gcc-16parses the SDK cleanly. Searching newest-first (gcc-16 … gcc-13) resolves this.2. With GCC 16,
-Osfails to linkstd::string's move constructorThe
MinSizeDebugbuild type compiles the host build at-Os. Homebrew GCC 16 at-Osemits an undefined reference to the unifiedC4constructor variant of the extern-templatestd::__cxx11::basic_string, which the shipped libstdc++ exports only asC1/C2(static libstdc++ lacksC4too). Test executables then fail to link:Minimal reproducer (Homebrew g++-16, macOS arm64):
g++-16 -Os …→ link fails (undefined...basic_stringIcSt11char_traitsIcESaIcEEC4EOS4_)g++-16 -O0 …/g++-16 -O2 …→ links (move ctor is inlined, noC4reference)The host test build has no size constraint, so building it at
-O2sidesteps the miscompile and is arguably more appropriate for host unit tests anyway.3.
--start-group/--end-groupis enabled for GNU on macOS, where Appleldrejects itCMakeLists.txt(lines ~18–24):The Clang branch is correctly restricted to
Linux, but the GNU branch has no platform guard. Homebrew GCC on macOS drives Apple'sld, which does not support the GNU archive-group flags:(Clang on macOS avoids this only because its branch requires
Linux.) AddingAND NOT APPLEto the GNU branch fixes it; the bare-metalarm-none-eabicross build is GNU withCMAKE_SYSTEM_NAME=Generic(notAPPLE), so it keeps the group flags its GNUldneeds.4.
-Werror=uninitializedinCortexProcessor::GetRevision()modules/jarnax/source/CortexProcessor.cpp(~line 68):Under GCC,
-Werror=uninitializedfires (the supervisor path writesrevisionthrough a pointer that GCC can't see through). The siblingGetPartNumber()initializes its local (partno = cortex::PartNumber::Unknown);GetRevision()should likewise value-initialize (cortex::Revision revision{};). Clang does not diagnose this.Suggested fixes
native-gcc.cmake: search newest GCC first (gcc-16 gcc-15 gcc-14 gcc-13 gcc).native-gcc.cmake: build the host at-O2(host tests are not size-constrained), avoiding the GCC-16-Osstd::stringC4link failure.CMakeLists.txt: addAND NOT APPLEto the GNU branch of the RESCAN link-group check.CortexProcessor.cpp: value-initializecortex::Revision revision{};.Environment
xnu_static_assert_struct_sizemacros).gcc@13,gcc@14,gcc@16installed.native-clanghost preset builds and tests cleanly.