cmake: Do not link an executable to detect the compiler.#19507
Open
casaroli wants to merge 1 commit into
Open
Conversation
casaroli
force-pushed
the
fix-cmake-try-compile
branch
2 times, most recently
from
July 23, 2026 06:55
6cfd507 to
22f8bf8
Compare
xiaoxiang781216
previously approved these changes
Jul 23, 2026
jerpelea
previously approved these changes
Jul 23, 2026
| # Building a static library instead exercises the compiler and stops short of | ||
| # the link, which is the documented approach for this case. | ||
|
|
||
| set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) |
Contributor
There was a problem hiding this comment.
should we move to a more common places? since it isn't specific to arm.
Contributor
Author
There was a problem hiding this comment.
maybe this is valid for x86 as well, on bare-metal only architectures I think it might not make sense.
I am ok with moving this to somewhere more generic. Where do you suggest?
I think we would need to make sure this is not included in the sim target. Right? WDYT?
Contributor
There was a problem hiding this comment.
or move to each arch's cmake file
Contributor
Author
There was a problem hiding this comment.
moved to top level CMakeLists and guarded against simmoved to top level CMakeLists and guarded against sim
acassis
previously approved these changes
Jul 23, 2026
casaroli
force-pushed
the
fix-cmake-try-compile
branch
from
July 23, 2026 17:03
22f8bf8 to
c4c8b32
Compare
CMake validates a compiler by building and linking a test program. For a bare metal cross toolchain that link cannot succeed on its own terms, and the flags NuttX supplies for it assume a toolchain shipped with newlib: gcc.cmake sets set(CMAKE_EXE_LINKER_FLAGS_INIT "--specs=nosys.specs") A perfectly usable arm-none-eabi-gcc built without those specs therefore fails configuration before a single NuttX source file is considered: arm-none-eabi-gcc: fatal error: cannot read spec file 'nosys.specs': No such file or directory CMake Error: ... CMake will not be able to correctly generate this project. Setting CMAKE_TRY_COMPILE_TARGET_TYPE to STATIC_LIBRARY makes the detection step compile without linking, which is the documented approach for cross compiling to a bare metal target. Toolchains that do ship nosys.specs are unaffected: the flag only applies to CMake's own detection, not to the NuttX link. This is not arch specific, so it is set once in the top level CMakeLists.txt alongside the toolchain-file selection, before project() triggers detection. sim is excluded: it is hosted and links real host executables, so it keeps the usual executable-based detection. try_compile() reads the variable from the calling scope, so it takes effect without living in a toolchain file; tools/toolchain.cmake.export already sets the same for the exported build. Assisted-by: Claude Code:claude-opus-4-8 Assisted-by: Claude Code:claude-fable-5 Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
casaroli
dismissed stale reviews from acassis, jerpelea, and xiaoxiang781216
via
July 24, 2026 11:39
2de8b47
casaroli
force-pushed
the
fix-cmake-try-compile
branch
from
July 24, 2026 11:39
c4c8b32 to
2de8b47
Compare
xiaoxiang781216
approved these changes
Jul 24, 2026
acassis
approved these changes
Jul 24, 2026
acassis
approved these changes
Jul 24, 2026
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
CMake validates a compiler by building and linking a small test program.
For a bare-metal cross toolchain that link cannot succeed on its own terms — no
start files, no default linker script, no libc — and the flags NuttX supplies
for it assume a toolchain shipped with newlib.
arch/arm/src/cmake/gcc.cmakesets:
A perfectly usable
arm-none-eabi-gccbuilt without those specs thereforefails configuration before a single NuttX source file is considered.
Setting
CMAKE_TRY_COMPILE_TARGET_TYPEtoSTATIC_LIBRARYmakes the detectionstep compile without linking. This is the approach CMake documents for
cross-compiling to bare metal, and NuttX does not currently set it anywhere in
the tree.
The issue is not ARM-specific, so the setting lives in the top-level
CMakeLists.txt, in the block that already selectsCMAKE_TOOLCHAIN_FILEbefore
project()triggers detection.simis excluded: it is hosted andlinks real host executables, so it keeps the usual executable-based detection.
try_compile()reads the variable from the calling scope, so it takes effectfrom there without having to live in a toolchain file — and
tools/toolchain.cmake.exportalready sets the same line for the exportedbuild, confirming it is generic rather than arch-specific.
Impact
that lacks
nosys.specs, including the Homebrewarm-none-eabi-gccand othernewlib-less builds. Previously it could not configure at all.
nosys.specs: unaffected. The setting appliesonly to CMake's own compiler-detection step, not to the NuttX link.
sim: unaffected — excluded by theCONFIG_ARCHguard, so hosteddetection is exactly as before.
the same newlib-less detection failure benefits, not just ARM.
Testing
Board:
mps3-an547:picostest, CMake + Ninja generator.Before (master
7df7c6ee):After this patch, configuration succeeds:
and the tree then compiles — 1248 objects built:
The build stops at the final link, for a reason this patch does not address and
does not introduce:
That is the NuttX link itself passing
--specs=nosys.specs(
gcc.cmake:277), not CMake's detection step. With this patch the compilephase is fully exercised on a newlib-less toolchain, where before nothing could
be configured.
(
CONFIG_LIBM=y/CONFIG_LIBM_TOOLCHAIN=nwas set for the run above, for thesame missing-newlib reason.)
Regression check on a toolchain that does ship newlib
The obvious question is whether this weakens compiler detection where it
currently works. Repeating the configure step with the Arm GNU Toolchain
15.2.Rel1:
nosys.specs)nosys.specs)So the patch strictly widens the set of usable toolchains.
With the newlib toolchain the build then proceeds through 1120 objects and
stops at the final link — again identically with and without this patch:
That is this board config not linking its applications, which reproduces on
unmodified master and is unrelated to this change. I mention it only so the
absence of a
nuttxbinary in these logs is not mistaken for a regression.Re-verified from the top-level location
With the setting moved to
CMakeLists.txt,mps3-an547:picostestconfiguresidentically —
Check for working C compiler … skippedconfirmsCMAKE_TRY_COMPILE_TARGET_TYPEtakes effect from the top-level scope, so itdoes not need to reside in a toolchain file.
tools/checkpatch.sh -c -u -m -gpasses on the change.