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

关于在CMake工具链中获取无后缀<TARGET>以解决自定义C编译器多输出文件问题的问询

Solution for Custom Compiler Outputs in CMake Toolchain

This is a common pain point when working with embedded or custom compilers in CMake, so let's break down a clean toolchain-level fix that avoids both redundant linking and unwanted file suffixes.

Core Approach

The key is to leverage CMake's generator expressions to get the suffix-free target name directly in your toolchain configuration, while still letting CMake properly track the main ELF output to prevent redundant builds.

Step 1: Set the ELF Suffix for C Executables

First, tell CMake that your C executables use the .elf suffix. This fixes the redundant linking issue because CMake will now recognize the .elf file as the official target output and track its dependencies correctly:

set(CMAKE_EXECUTABLE_SUFFIX_C ".elf")

In your CMAKE_C_LINK_EXECUTABLE setting, use the $<TARGET_NAME> generator expression to reference the suffix-free target name for your HEX and MAP outputs. This ensures those files don't inherit the .elf suffix:

set(CMAKE_C_LINK_EXECUTABLE
  "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>
   -o <TARGET>
   --elf-output <TARGET>
   --hex-output $<TARGET_FILE_DIR:<TARGET>>/$<TARGET_NAME>.hex
   --map-output $<TARGET_FILE_DIR:<TARGET>>/$<TARGET_NAME>.map"
)
  • $<TARGET_NAME> resolves to the exact name you passed to add_executable (e.g., foo for add_executable(foo src/main.c)), so your outputs become foo.elf, foo.hex, and foo.map.
  • $<TARGET_FILE_DIR:<TARGET>> ensures the HEX/MAP files are placed in the same directory as the ELF file, which is useful if you're using subdirectories or out-of-source builds.

Step 3: Add Clean Rules for Extra Outputs (Optional)

To make sure make clean removes the HEX and MAP files too, add a function in your toolchain to automatically set the ADDITIONAL_MAKE_CLEAN_FILES property for all C executable targets:

# Auto-add clean rules for HEX/MAP files
function(add_additional_clean_files target)
  get_target_property(target_type ${target} TYPE)
  if(target_type STREQUAL "EXECUTABLE")
    set_target_properties(${target} PROPERTIES
      ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${target}.hex;${CMAKE_CURRENT_BINARY_DIR}/${target}.map"
    )
  endif()
endfunction()

# Apply the function to all targets (CMake 3.20+)
cmake_language(DEFER DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} CALL add_additional_clean_files ${CMAKE_CURRENT_TARGET})

For older CMake versions (pre-3.20), you can use a project include file to iterate over all targets after they're created:

# In your toolchain file
set(CMAKE_PROJECT_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/clean_extra_outputs.cmake)

# clean_extra_outputs.cmake
foreach(target ${CMAKE_PROJECT_TARGETS})
  get_target_property(target_type ${target} TYPE)
  if(target_type STREQUAL "EXECUTABLE")
    set_target_properties(${target} PROPERTIES
      ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${target}.hex;${CMAKE_CURRENT_BINARY_DIR}/${target}.map"
    )
  endif()
endforeach()

Why This Works

  • No Redundant Linking: By setting CMAKE_EXECUTABLE_SUFFIX_C, CMake correctly identifies the .elf file as the primary target output. It will only re-run the linker if dependencies (object files, flags, etc.) change.
  • Clean File Names: $<TARGET_NAME> gives you the raw target name without any suffixes, so your HEX/MAP files don't end up with .elf.hex or .elf.map.
  • Toolchain-Level Logic: All configuration stays in your toolchain file, so project-level CMake code doesn't need extra boilerplate.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:07:41