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)

Reply via email to