cmake: Do not link an executable to detect the compiler.

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>
This commit is contained in:
Marco Casaroli 2026-07-23 08:32:18 +02:00 committed by Xiang Xiao
parent 4a64703a60
commit 7eb6a3ca59

View file

@ -475,6 +475,19 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/arch/${CONFIG_ARCH}/src/cmake)
set(CMAKE_TOOLCHAIN_FILE
"${CMAKE_SOURCE_DIR}/arch/${CONFIG_ARCH}/src/cmake/Toolchain.cmake")
# Compiler detection must not try to link a full executable. CMake validates a
# compiler by building and linking a test program, but a bare metal cross
# toolchain has no start files, default linker script or libc, and the link
# flags NuttX supplies assume a newlib toolchain (--specs=nosys.specs). A
# usable cross gcc without those specs then fails configuration before any NuttX
# source is considered. Building a static library instead exercises the
# compiler and stops short of the link. sim is hosted and links normally, so it
# keeps the usual executable-based detection.
if(NOT CONFIG_ARCH STREQUAL "sim")
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
endif()
# Define project #############################################################
# This triggers configuration