This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 1fb5dd1ddab cmake: Fix cross-compilation support in add_subdirectory
mode
1fb5dd1ddab is described below
commit 1fb5dd1ddaba2f01bb56fc4197cbdc7a1892555c
Author: Swatantra Yadav <[email protected]>
AuthorDate: Wed Oct 21 14:02:35 2026 +0530
cmake: Fix cross-compilation support in add_subdirectory mode
When NuttX is embedded in an external project via add_subdirectory(),
several issues prevented cross-compiling non-sim architectures:
1. In arch/{arm,arm64,risc-v,tricore,x86_64,xtensa}/src/CMakeLists.txt and
boards/CMakeLists.txt, the arguments to add_subdirectory() had
EXCLUDE_FROM_ALL and binary_dir inverted, violating CMake syntax
add_subdirectory(source_dir binary_dir [EXCLUDE_FROM_ALL]).
2. arch/arm/src/cmake/Toolchain.cmake and
arch/arm64/src/cmake/Toolchain.cmake
used include() without CMAKE_CURRENT_LIST_DIR, failing to find sibling
toolchain files when CMAKE_MODULE_PATH was not set in parent scope.
3. In subproject mode, resolve and safely evaluate CMAKE_TOOLCHAIN_FILE
(handling relative paths and cache entries per CMake lookup rules) once
NuttX configuration is exported so architecture settings (e.g.
ARCH_SUBDIR,
ARCHCPUFLAGS) are populated.
4. Export CMAKE_TOOLCHAIN_FILE, CMAKE_MODULE_PATH, and all CONFIG_*
variables to PARENT_SCOPE so parent projects can access configuration
and build targets with the cross-compiler.
5. Add a diagnostic check inspecting the active compiler executable
driver basename against TOOLCHAIN_PREFIX, providing clear guidance
to configure CMAKE_TOOLCHAIN_FILE before the parent project's first
project() call if a mismatched compiler is detected.
Fixes #19697.
Signed-off-by: Swatantra Yadav <[email protected]>
---
CMakeLists.txt | 81 +++++++++++++++++++++++++++++++++++-
arch/arm/src/CMakeLists.txt | 2 +-
arch/arm/src/cmake/Toolchain.cmake | 4 +-
arch/arm64/src/CMakeLists.txt | 2 +-
arch/arm64/src/cmake/Toolchain.cmake | 4 +-
arch/risc-v/src/CMakeLists.txt | 2 +-
arch/tricore/src/CMakeLists.txt | 2 +-
arch/x86_64/src/CMakeLists.txt | 2 +-
arch/xtensa/src/CMakeLists.txt | 2 +-
boards/CMakeLists.txt | 10 ++---
10 files changed, 94 insertions(+), 17 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e05b944bc2b..c429834e9d8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -482,8 +482,28 @@ endif()
# This needs to happen before project() when binaries are searched for
list(APPEND CMAKE_MODULE_PATH ${NUTTX_DIR}/arch/${CONFIG_ARCH}/src/cmake)
-set(CMAKE_TOOLCHAIN_FILE
- "${NUTTX_DIR}/arch/${CONFIG_ARCH}/src/cmake/Toolchain.cmake")
+
+macro(nuttx_resolve_toolchain_file)
+ if(CMAKE_TOOLCHAIN_FILE AND NOT IS_ABSOLUTE "${CMAKE_TOOLCHAIN_FILE}")
+ if(EXISTS "${CMAKE_BINARY_DIR}/${CMAKE_TOOLCHAIN_FILE}")
+ set(CMAKE_TOOLCHAIN_FILE "${CMAKE_BINARY_DIR}/${CMAKE_TOOLCHAIN_FILE}")
+ elseif(EXISTS "${CMAKE_SOURCE_DIR}/${CMAKE_TOOLCHAIN_FILE}")
+ set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/${CMAKE_TOOLCHAIN_FILE}")
+ elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_TOOLCHAIN_FILE}")
+ set(CMAKE_TOOLCHAIN_FILE
+ "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_TOOLCHAIN_FILE}")
+ endif()
+ endif()
+endmacro()
+
+# Resolve CMAKE_TOOLCHAIN_FILE if provided by parent or cache, or default to
the
+# architecture toolchain file for standalone builds.
+if(CMAKE_TOOLCHAIN_FILE)
+ nuttx_resolve_toolchain_file()
+else()
+ set(CMAKE_TOOLCHAIN_FILE
+ "${NUTTX_DIR}/arch/${CONFIG_ARCH}/src/cmake/Toolchain.cmake")
+endif()
# 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
@@ -503,6 +523,63 @@ endif()
project(NuttX LANGUAGES C CXX ASM)
+# When NuttX is embedded as a subproject via add_subdirectory(), CMake will not
+# automatically load CMAKE_TOOLCHAIN_FILE during project() if the parent
project
+# already enabled languages. Explicitly include it to ensure architecture
+# settings, compiler definitions, and ARCH_SUBDIR are populated.
+if(NOT CMAKE_SOURCE_DIR STREQUAL NUTTX_DIR)
+ # Capture the compiler selected during language initialization before
+ # including the toolchain file, as the toolchain will assign CMAKE_C_COMPILER
+ # to the cross-compiler executable.
+ if(CMAKE_C_COMPILER)
+ set(_active_c_compiler "${CMAKE_C_COMPILER}")
+ elseif(DEFINED CACHE{CMAKE_C_COMPILER})
+ set(_active_c_compiler "$CACHE{CMAKE_C_COMPILER}")
+ endif()
+
+ # Ensure CMAKE_TOOLCHAIN_FILE is resolved using lookup rules before testing
+ # existence, in case a relative path was provided.
+ if(CMAKE_TOOLCHAIN_FILE)
+ nuttx_resolve_toolchain_file()
+
+ if(EXISTS "${CMAKE_TOOLCHAIN_FILE}" AND NOT IS_DIRECTORY
+ "${CMAKE_TOOLCHAIN_FILE}")
+ include(${CMAKE_TOOLCHAIN_FILE})
+ endif()
+ endif()
+
+ if(NOT CONFIG_ARCH STREQUAL "sim" AND _active_c_compiler)
+ if(TOOLCHAIN_PREFIX)
+ get_filename_component(_compiler_name "${_active_c_compiler}" NAME)
+ string(FIND "${_compiler_name}" "${TOOLCHAIN_PREFIX}" _prefix_pos)
+ if(NOT _prefix_pos EQUAL 0)
+ message(
+ FATAL_ERROR
+ "Active C compiler '${_active_c_compiler}' does not match expected
"
+ "toolchain prefix '${TOOLCHAIN_PREFIX}'. When embedding NuttX via "
+ "add_subdirectory(), configure CMAKE_TOOLCHAIN_FILE before the "
+ "parent project's project() call.")
+ endif()
+ unset(_compiler_name)
+ unset(_prefix_pos)
+ endif()
+ endif()
+ unset(_active_c_compiler)
+
+ set(CMAKE_TOOLCHAIN_FILE
+ "${CMAKE_TOOLCHAIN_FILE}"
+ PARENT_SCOPE)
+ set(CMAKE_MODULE_PATH
+ "${CMAKE_MODULE_PATH}"
+ PARENT_SCOPE)
+ get_property(config_keys GLOBAL PROPERTY NUTTX_CONFIG_KEYS)
+ foreach(key ${config_keys})
+ set(${key}
+ ${${key}}
+ PARENT_SCOPE)
+ endforeach()
+endif()
+
# include common toolchain setting
include(nuttx_toolchain)
diff --git a/arch/arm/src/CMakeLists.txt b/arch/arm/src/CMakeLists.txt
index 4f9ff8d089b..03c25bc556b 100644
--- a/arch/arm/src/CMakeLists.txt
+++ b/arch/arm/src/CMakeLists.txt
@@ -21,7 +21,7 @@
#
##############################################################################
add_subdirectory(${ARCH_SUBDIR})
-add_subdirectory(${NUTTX_CHIP_ABS_DIR} EXCLUDE_FROM_ALL exclude_chip)
+add_subdirectory(${NUTTX_CHIP_ABS_DIR} exclude_chip EXCLUDE_FROM_ALL)
add_subdirectory(common)
# Include directories (before system ones) as PUBLIC so that it can be exposed
diff --git a/arch/arm/src/cmake/Toolchain.cmake
b/arch/arm/src/cmake/Toolchain.cmake
index cd3b2a630c9..f7c41692b48 100644
--- a/arch/arm/src/cmake/Toolchain.cmake
+++ b/arch/arm/src/cmake/Toolchain.cmake
@@ -43,7 +43,7 @@ else() # ARM9, ARM7TDMI, etc.
set(ARCH_SUBDIR arm)
endif()
-include(${ARCH_SUBDIR})
+include(${CMAKE_CURRENT_LIST_DIR}/${ARCH_SUBDIR}.cmake)
# include the toolchain specific cmake file
@@ -59,4 +59,4 @@ else() # gcc
set(TOOLCHAIN_FILE gcc)
endif()
-include(${TOOLCHAIN_FILE})
+include(${CMAKE_CURRENT_LIST_DIR}/${TOOLCHAIN_FILE}.cmake)
diff --git a/arch/arm64/src/CMakeLists.txt b/arch/arm64/src/CMakeLists.txt
index 57a2429f2f0..fa5fcc363c7 100644
--- a/arch/arm64/src/CMakeLists.txt
+++ b/arch/arm64/src/CMakeLists.txt
@@ -20,7 +20,7 @@
#
#
##############################################################################
add_subdirectory(common)
-add_subdirectory(${NUTTX_CHIP_ABS_DIR} EXCLUDE_FROM_ALL exclude_chip)
+add_subdirectory(${NUTTX_CHIP_ABS_DIR} exclude_chip EXCLUDE_FROM_ALL)
# Include directories (before system ones) as PUBLIC so that it can be exposed
# to libboard
target_include_directories(arch BEFORE PUBLIC ${NUTTX_CHIP_ABS_DIR} common)
diff --git a/arch/arm64/src/cmake/Toolchain.cmake
b/arch/arm64/src/cmake/Toolchain.cmake
index 0ff14f48c33..fd7c09555c5 100644
--- a/arch/arm64/src/cmake/Toolchain.cmake
+++ b/arch/arm64/src/cmake/Toolchain.cmake
@@ -48,7 +48,7 @@ endif()
# include the toolchain specific cmake file
if(CONFIG_ARCH_TOOLCHAIN_CLANG)
- include(clang)
+ include(${CMAKE_CURRENT_LIST_DIR}/clang.cmake)
elseif(CONFIG_ARCH_TOOLCHAIN_GCC) # gcc
- include(gcc)
+ include(${CMAKE_CURRENT_LIST_DIR}/gcc.cmake)
endif()
diff --git a/arch/risc-v/src/CMakeLists.txt b/arch/risc-v/src/CMakeLists.txt
index 7047ecc0582..7c5b9760ce2 100644
--- a/arch/risc-v/src/CMakeLists.txt
+++ b/arch/risc-v/src/CMakeLists.txt
@@ -20,7 +20,7 @@
#
#
##############################################################################
-add_subdirectory(${NUTTX_CHIP_ABS_DIR} EXCLUDE_FROM_ALL exclude_chip)
+add_subdirectory(${NUTTX_CHIP_ABS_DIR} exclude_chip EXCLUDE_FROM_ALL)
add_subdirectory(common)
if(CONFIG_BUILD_KERNEL)
diff --git a/arch/tricore/src/CMakeLists.txt b/arch/tricore/src/CMakeLists.txt
index 9f2686a11ce..a41ca24b43f 100644
--- a/arch/tricore/src/CMakeLists.txt
+++ b/arch/tricore/src/CMakeLists.txt
@@ -21,7 +21,7 @@
#
##############################################################################
add_subdirectory(${ARCH_SUBDIR})
-add_subdirectory(${NUTTX_CHIP_ABS_DIR} EXCLUDE_FROM_ALL exclude_chip)
+add_subdirectory(${NUTTX_CHIP_ABS_DIR} exclude_chip EXCLUDE_FROM_ALL)
add_subdirectory(common)
# Include directories (before system ones) as PUBLIC so that it can be exposed
diff --git a/arch/x86_64/src/CMakeLists.txt b/arch/x86_64/src/CMakeLists.txt
index eb309b463e0..15837236744 100644
--- a/arch/x86_64/src/CMakeLists.txt
+++ b/arch/x86_64/src/CMakeLists.txt
@@ -21,7 +21,7 @@
#
##############################################################################
add_subdirectory(${ARCH_SUBDIR})
-add_subdirectory(${NUTTX_CHIP_ABS_DIR} EXCLUDE_FROM_ALL exclude_chip)
+add_subdirectory(${NUTTX_CHIP_ABS_DIR} exclude_chip EXCLUDE_FROM_ALL)
add_subdirectory(common)
# Include directories (before system ones) as PUBLIC so that it can be exposed
diff --git a/arch/xtensa/src/CMakeLists.txt b/arch/xtensa/src/CMakeLists.txt
index d05cbaf827b..e2e18a97f5d 100644
--- a/arch/xtensa/src/CMakeLists.txt
+++ b/arch/xtensa/src/CMakeLists.txt
@@ -21,7 +21,7 @@
#
##############################################################################
add_subdirectory(common)
-add_subdirectory(${NUTTX_CHIP_ABS_DIR} EXCLUDE_FROM_ALL exclude_chip)
+add_subdirectory(${NUTTX_CHIP_ABS_DIR} exclude_chip EXCLUDE_FROM_ALL)
# Include directories (before system ones) as PUBLIC so that it can be exposed
# to libboard
target_include_directories(arch BEFORE PUBLIC ${NUTTX_CHIP_ABS_DIR} common)
diff --git a/boards/CMakeLists.txt b/boards/CMakeLists.txt
index a8e85345ff0..29bdd58179b 100644
--- a/boards/CMakeLists.txt
+++ b/boards/CMakeLists.txt
@@ -49,8 +49,8 @@ target_include_directories(board
# if found at each arch and soc level
if(EXISTS ${NUTTX_BOARD_ABS_DIR}/../common/CMakeLists.txt)
- add_subdirectory("${NUTTX_BOARD_ABS_DIR}/../common" EXCLUDE_FROM_ALL
- exclude_common)
+ add_subdirectory("${NUTTX_BOARD_ABS_DIR}/../common" exclude_common
+ EXCLUDE_FROM_ALL)
# Create link ARCH_SRC_BOARD_BOARD_SYMLINK
@@ -60,8 +60,8 @@ if(EXISTS ${NUTTX_BOARD_ABS_DIR}/../common/CMakeLists.txt)
endif()
if(EXISTS ${NUTTX_BOARD_ABS_DIR}/../drivers/CMakeLists.txt)
- add_subdirectory("${NUTTX_BOARD_ABS_DIR}/../drivers" EXCLUDE_FROM_ALL
- exclude_drivers)
+ add_subdirectory("${NUTTX_BOARD_ABS_DIR}/../drivers" exclude_drivers
+ EXCLUDE_FROM_ALL)
endif()
-add_subdirectory(${NUTTX_BOARD_ABS_DIR} EXCLUDE_FROM_ALL exclude_board)
+add_subdirectory(${NUTTX_BOARD_ABS_DIR} exclude_board EXCLUDE_FROM_ALL)