如何在CMake中通过接口库传递文件级依赖(自定义命令+自定义目标)
Fixing CMake Relink Issue When Modifying Linker Script Source Files
这个问题的核心在于: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
相关产品推荐
相关产品推荐

