You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CMake项目中仅交叉编译指定目标的实现方法

Targeted Cross-Compilation for Specific CMake Targets (No Global Reconfiguration)

Hey there, I totally get the frustration of having to use a global toolchain file when you only need to cross-compile specific targets—like an embedded unit test suite using Google Test—while keeping the rest of your project building with the host compiler. Let's walk through practical, low-fuss approaches to make this work, along with minimal examples.

Approach 1: Isolate Cross-Compiled Targets with ExternalProject_Add

This is the cleanest method because it creates a completely separate build context for your cross-compiled targets, using your existing toolchain file without touching the rest of your project.

Example Main CMakeLists.txt

# Build your main embedded application with the host compiler (default setup)
add_executable(embedded_firmware src/main.c src/driver.c)

# Set up the cross-compiled test target as an external project
include(ExternalProject)
ExternalProject_Add(
    embedded_unit_tests
    SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests
    # Pass your toolchain file to the external project's CMake invocation
    CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/your_toolchain.cmake
    BUILD_ALWAYS ON  # Rebuild whenever test sources change
    INSTALL_COMMAND ""  # Skip installation since we just need the test binary
)

Example Tests/CMakeLists.txt

In this subdirectory, you can set up Google Test just like you would for a normal project—CMake will use the toolchain file you passed to handle cross-compilation:

# Make sure GTest is either cross-compiled alongside or pre-built for your target
find_package(GTest REQUIRED)

add_executable(unit_test_suite test_driver.cpp test_utils.cpp)
target_link_libraries(unit_test_suite GTest::GTest GTest::Main)

Approach 2: Conditionally Apply Toolchain to Subdirectories

If you prefer keeping everything in a single CMake project, you can temporarily set the toolchain file before adding a subdirectory, then reset it afterward. Note: This can have side effects if you're not careful, so use it only for simple setups.

Example

# Main project: builds with host compiler
add_executable(host_utils src/host_utils.c)

# Switch to cross-compile toolchain for the tests subdirectory
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/your_toolchain.cmake)
add_subdirectory(tests)
# Reset the toolchain to avoid affecting subsequent targets
unset(CMAKE_TOOLCHAIN_FILE)

Approach 3: Quick Custom Target for Simple Cases

For tiny cross-compiled targets, you can skip CMake's internal configuration and directly invoke your cross-compiler via a custom target:

# Host-side build
add_executable(embedded_app src/main.c)

# Define your cross-compiler path (can also pass via command line)
set(CROSS_CC "C:/path/to/your/cross-gcc.exe")
set(CROSS_CXX "C:/path/to/your/cross-g++.exe")

# Cross-compiled test target
add_custom_target(
    cross_compiled_test
    COMMAND ${CROSS_CXX} ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_main.cpp -o test_binary -lgtest -lgtest_main
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_main.cpp
    COMMENT "Cross-compiling unit test..."
)

Your Toolchain File (Cleaned Up)

Just to keep things aligned, here's your simplified toolchain file with proper formatting:

SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_C_COMPILER "C:/path/to/your/cross-compiler.exe")
SET(CMAKE_CXX_COMPILER "C:/path/to/your/cross-cxx.exe")
SET(CMAKE_FIND_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/ghs")

# Adjust find command behavior
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Pro Tips

  • Reuse your toolchain file: You don't need to duplicate toolchain definitions—just pass the same file to whichever build context needs cross-compilation.
  • Google Test for embedded: If GTest isn't pre-built for your target, use ExternalProject_Add to build GTest with the same toolchain file before building your tests.
  • Avoid global overrides: The ExternalProject method is the most reliable because it prevents conflicts between host and target compiler settings.

内容的提问来源于stack exchange,提问作者sruli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:01:08