【问题标题】:CMake: How to specify a different link script for each targetCMake:如何为每个目标指定不同的链接脚本
【发布时间】:2019-05-02 19:46:15
【问题描述】:

我在 CMake 项目中创建了多个目标。每个目标都有不同的链接脚本(LD 文件)。如何编写 CMakeLists.txt 文件来实现这一点?这适用于带有 C/C++/ASM 文件的嵌入式项目。

这是我目前所拥有的。问题是 LINKER_SCRIPT 是全局定义的,而不是针对每个目标的。

# add alpha target
add_executable(alpha.elf ${SOURCES})
target_compile_definitions(alpha.elf PUBLIC -DALPHA_DEFINED)
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/Linker/alpha.ld)

# add beta target
add_executable(beta.elf ${SOURCES})
target_compile_definitions(beta.elf PUBLIC -DBETA_DEFINED)
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/Linker/beta.ld)

set(CMAKE_EXE_LINKER_FLAGS
    "${CMAKE_EXE_LINKER_FLAGS} -T ${LINKER_SCRIPT}")

问题是 LINKER_SCRIPT 被覆盖,最后一个定义是使用的。我怎样才能做到这一点?

我尝试使用以下方法定义每个目标变量,但输出与预期不符。该文件被编译,但是事情不在他们应该在的地方。例如,生成的 HEX 文件不是从 0x08000000 开始,而这应该是每个 LD 文件定义的位置。

set_target_properties(alpha.elf PROPERTIES
        CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=${PROJECT_BINARY_DIR}/alpha.elf.map -T ${CMAKE_SOURCE_DIR}/Linker/alpha.ld")

【问题讨论】:

    标签: cmake linker


    【解决方案1】:

    变量LINKER_SCRIPT 只是在您第二次将其设置为一个值时被覆盖。它没有全局范围,而是子目录/函数范围。但就像任何变量一样,它采用其最新值。

    CMAKE_EXE_LINKER_FLAGS 在这种情况下被用于两个目标。将其拆分为单独的子目录可能有效,但我从未尝试过。

    我知道没有针对每个目标的变量。 set_target_properties 用于设置属性。 CMake 知道某些属性,但属性CMAKE_EXE_LINKER_FLAGS 不是其中之一。在生成构建文件时应该忽略它。

    尝试使用target_link_options 设置每个目标的属性LINK_OPTIONS,这是已知的,并且在链接可执行文件时会显示该选项。

    例如target_link_options(alpha.elf PRIVATE -T${CMAKE_SOURCE_DIR}/Linker/alpha.ld)。我没有将它与其中有空格的选项一起使用,所以这可能是个问题。

    如果链接描述文件发生更改,要重新链接,请参考以下答案: https://stackoverflow.com/a/42138375/1028434

    【讨论】:

    • "CMAKE_EXE_LINKER_FLAGS 是一个全局变量。" - 你确定它是全球性的吗?我对 CMAKE_CXX_FLAGS 变量也有同样的想法,但最近发现它实际上是 per-directory 一个。 (也就是说,将其设置在子目录中不会重新定义顶级设置)。
    • @Tsyvarev 好点。我已经更新了答案。完全有道理。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    相关资源
    最近更新 更多