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

如何在CMake中通过接口库传递文件级依赖(自定义命令+自定义目标)

这个问题的核心在于:CMake默认不会解析链接选项中的文件路径,所以即使你通过接口库传递了链接脚本的使用意图,它也不知道应用的链接步骤依赖于生成后的linker-script.ld文件。仅通过add_dependencies添加目标级依赖只能保证链接脚本被生成,但无法触发应用的重链接。

解决方案

我们需要明确告诉CMake,应用的链接步骤依赖于生成的链接脚本文件。可以通过以下修改你的CMakeLists.txt来实现:

cmake_minimum_required(VERSION 3.1)
project(a_test)

add_custom_command(OUTPUT linker-script.ld
    COMMAND cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/linker-script.ld-source linker-script.ld
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/linker-script.ld-source)
add_custom_target(linker-script DEPENDS linker-script.ld)

add_library(static-library STATIC dummy.c)

add_library(interface-library INTERFACE)
target_link_libraries(interface-library INTERFACE static-library)

# 1. 传递链接脚本的使用选项给所有依赖此接口库的目标
target_link_options(interface-library INTERFACE "-T${CMAKE_CURRENT_BINARY_DIR}/linker-script.ld")
# 2. 明确声明链接时依赖生成的链接脚本文件
set_property(TARGET interface-library APPEND PROPERTY INTERFACE_LINK_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/linker-script.ld")
# 3. 保证链接脚本在使用前已生成
add_dependencies(interface-library linker-script)

add_executable(application main.c)
target_link_libraries(application interface-library)

为什么这能解决问题

  • target_link_options:把-Tlinker-script.ld链接选项传递给应用,实现你原本想用链接脚本的意图。
  • INTERFACE_LINK_DEPENDS:这是关键!它告诉CMake,任何链接到interface-library的目标(比如这里的application),其链接步骤依赖于指定的linker-script.ld文件。当这个文件的内容或时间戳更新时,CMake会自动触发应用的重链接。
  • add_dependencies:确保在构建依赖interface-library的目标之前,先生成linker-script.ld文件,避免链接时找不到文件的错误。

测试效果

修改linker-script.ld-source后再次运行make,你会看到:

[ 40%] Built target static-library
[ 60%] Generating linker-script.ld
[ 60%] Built target linker-script
[100%] Linking C executable application
[100%] Built target application

此时应用会重新执行链接步骤,符合你的预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:09:11