【问题标题】:How do I tell CMake to specify multiple linker script files to GCC?如何告诉 CMake 为 GCC 指定多个链接器脚本文件?
【发布时间】:2020-06-19 21:21:26
【问题描述】:

我正在使用 CMake 3.17 和 GNU ARM 工具链,我正在尝试将构建从 Eclipse 迁移到 CMake。Eclipse 构建的一部分指定了要在链接时使用的多个链接器脚本文件,因此我设置了我的 CMakeLists。 txt 文件如下:

target_link_options(${application_name} PRIVATE
    -mcpu=cortex-m4
    -mthumb 
    -mfloat-abi=hard 
    -mfpu=fpv4-sp-d16 
    -fmessage-length=0 
    -fsigned-char 
    -ffunction-sections 
    -fdata-sections 
    -flto 
    -Wall
    -Xlinker --gc-sections 
    -Wl,-Map,${map_file}
    -T ${CMAKE_SOURCE_DIR}/ldscripts/libs.ld
    -T ${CMAKE_SOURCE_DIR}/ldscripts/mem.ld
    -T ${CMAKE_SOURCE_DIR}/ldscripts/sections.ld
)

但是当我运行make 时,-T 选项被第二个和第三个文件吞没了。这是我在成功编译所有源代码后运行make VERBOSE=1 时得到的结果。链接器命令行后跟有关缺少 -T 选项的警告:

Linking CXX executable StartupSequence.elf
/D/gcc-arm-none-eabi-9-2019-q4/bin/arm-none-eabi-g++.exe    --specs=nano.specs --specs=nosys.specs -g -Og -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -flto -Wall -Xlinker --gc-sections -Wl,-Map,StartupSequence.map -T C:/svn/startup_sequence/ldscripts/libs.ld C:/svn/startup_sequence/ldscripts/mem.ld C:/svn/startup_sequence/ldscripts/sections.ld @CMakeFiles/StartupSequence.dir/objects1.rsp  -o StartupSequence.elf  ../Drivers/CMSIS/DSP/Lib/libarm_cortexM4lf_math.a ../Middlewares/Third_Party/mbedTLS/library/libmbedcrypto.a
d:/gcc-arm-none-eabi-9-2019-q4/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: warning: C:/svn/startup_sequence/ldscripts/sections.ld contains output sections; did you forget -T?

为什么最后两个文件的-T 没有正确发送到命令行?

我尝试将链接脚本规范分成三个对target_link_options 的单独调用,并用双引号将每个脚本规范括起来,但似乎没有效果。

【问题讨论】:

  • 尝试将每个参数放在引号中? (例如,"-T ${CMAKE_SOURCE_DIR}/ldscripts/libs.ld" "-T ${CMAKE_SOURCE_DIR}/ldscripts/mem.ld"
  • 我试过了,但没有骰子。

标签: gcc cmake


【解决方案1】:

默认情况下,CMake de-duplicates 编译和链接选项。也就是说,多个-T 选项合并为一个选项。

CMake 不知道哪些选项实际上与进一步的参数绑定,但提供了一个SHELL: 机制来定义这些选项:

target_link_options(${application_name} PRIVATE
  "SHELL:-T ${CMAKE_SOURCE_DIR}/ldscripts/libs.ld"
  "SHELL:-T ${CMAKE_SOURCE_DIR}/ldscripts/mem.ld"
  "SHELL:-T ${CMAKE_SOURCE_DIR}/ldscripts/sections.ld"
)

documentation for target_link_options 命令中描述了此机制。


同样的机制适用于传递给target_compile_options 的编译器选项,请参阅questionmy answer

【讨论】:

  • 在看到这个并重新阅读文档后,我明白了现在发生了什么,并用这种方法解决了我的问题。谢谢!
【解决方案2】:

因为-T 被解释为单个选项。将-T 粘贴到路径上。试试:

-T${CMAKE_SOURCE_DIR}/ldscripts/libs.ld
-T${CMAKE_SOURCE_DIR}/ldscripts/mem.ld
-T${CMAKE_SOURCE_DIR}/ldscripts/sections.ld

【讨论】:

  • 这也有效。我选择上述作为答案,因为它似乎是一个更好的“长期解决方案”,并且还教会了我一些关于 CMake 的重要知识。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-24
  • 2020-10-01
  • 2011-09-28
  • 2012-12-09
  • 1970-01-01
  • 2018-02-01
相关资源
最近更新 更多