CMAKE分离链接器和编译器标志

3

现在我的toolchain.cmake看起来像这样:

CMAKE_FORCE_C_COMPILER(arm-none-eabi-gcc GNU)
CMAKE_FORCE_CXX_COMPILER(arm-none-eabi-gcc GNU)
SET(CMAKE_ASM_COMPILER arm-none-eabi-as)
SET(CMAKE_OBJCOPY arm-none-eabi-objcopy CACHE INTERNAL "objcopy" FORCE)
SET(CMAKE_OBJDUMP arm-none-eabi-objdump CACHE INTERNAL "objdump" FORCE)

# Compiler Flags 
SET(MCU_FLAGS "-mcpu=cortex-m3 -mthumb")
SET(CMAKE_BUILD_FLAGS "-O2 -g -mfpu=vfp -mfloat-abi=soft -Wa,-meabi=5 -ffunction-sections -fno-common -pedantic -Wall -Wextra -Wno-missing-field-initializers")
SET(CMAKE_C_FLAGS "${MCU_FLAGS} ${CMAKE_BUILD_FLAGS}"  CACHE INTERNAL "c compiler flags")
SET(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS} CACHE INTERNAL "cxx compiler flags")
SET(CMAKE_ASM_FLAGS "-g -mcpu=cortex-m3 -mthumb -mfpu=vfp -mfloat-abi=soft -meabi=5 -warn" CACHE INTERNAL "asm compiler flags")

SET(CMAKE_EXE_LINKER_FLAGS "-mcpu=cortex-m3 -mthumb -Wall -Wextra -Wno-missing-field-initializers -g -nostartfiles -Wl,-T1.ld,-M=1.map,--gc-sections" CACHE INTERNAL "exe link flags")

问题在于CMake将编译器标志额外传递给链接器!有没有办法将这两个分开?
另一件事是,如果我使用另一个编译器工具链(如Fujitsu Softtune),如何明确告诉CMake采用链接器而不是编译器来链接对象?
谢谢。
所以我最终解决了它。对于所有遇到同样问题的人,我将CMakelists更改如下:
add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C CXX ASM)
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES  LINK_FLAGS "${LD_FLAGS_STR} -m ${PROJECT_NAME}.map")
set(CMAKE_C_LINK_EXECUTABLE "FLNK907S.EXE  -o <TARGET> <LINK_FLAGS> <OBJECTS>")

它很好地运行着...

其中${LD_FLAGS_STR}只是我的链接器标志列表(自己的变量),而LNK907S.EXE是我正在使用的链接器的名称(Fujitsu)。


2
这里的答案似乎需要特定于项目的设置。我有同样的一般问题,不想在我尝试构建的每个十几个库和二进制文件中重复这些设置。 - Chris Morgan
嗨,我点了赞。我也遇到了同样的问题。我唯一的问题是,你有项目特定的设置。如果你能发布${LD_FLAGS_STR}和<TARGET><LINK_FLAGS><OBJECTS>是什么,那就太好了。 因为我也想减少/删除我的代码中未使用的部分。 - Shivansh Jagga
2个回答

0

尝试使用SET_TARGET_PROPERTIES分别设置链接标志:

SET(MCU_FLAGS "-mcpu=cortex-m3 -mthumb")
SET(CMAKE_BUILD_FLAGS "-O2 -g -mfpu=vfp -mfloat-abi=soft -Wa,-meabi=5 -ffunction-sections -fno-common -pedantic -Wall -Wextra -Wno-missing-field-initializers")
SET(CMAKE_C_FLAGS "${MCU_FLAGS} ${CMAKE_BUILD_FLAGS}")
SET(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS})
SET(CMAKE_ASM_FLAGS "-g -mcpu=cortex-m3 -mthumb -mfpu=vfp -mfloat-abi=soft -meabi=5 -warn")
SET_TARGET_PROPERTIES(FOO PROPERTIES LINK_FLAGS "-mcpu=cortex-m3 -mthumb -Wall -Wextra -Wno-missing-field-initializers -g -nostartfiles -Wl,-T1.ld,-M=1.map,--gc-sections")

在此,我假定您的可执行文件名为“FOO”。请注意,链接库是按目标指定的。如果您只需要针对目标使用特殊编译器标志,则也可以在SET_TARGET_PROPERTIES中使用COMPILE_FLAGS

我按照你说的更改了CMakeLists,但问题仍然存在。cmake调用相同的编译器进行编译和链接,几乎使用相同的标志!!只要我使用gcc进行编译和链接就没有问题,但是富士通的编译器和链接器完全不同(具有不同的标志)!! - arash javanmard
3
找不到好的CMake文档真是令人沮丧:( - arash javanmard
回应你的第一条评论,如果你可以尝试使用SET_TARGET_PROPERTIES中的COMPILE_FLAGS选项而不是SET_COMPILE_FLAG,那么可能会在编译器和链接器之间获得真正的区别。 - SethMMorton
这个 SET_COMPILE_FLAG() 是什么?在 cmake 的文档中没有找到它,而且当我使用它时会报错。我确实找到了类似 SET_COMPILE_FLAGS 的东西,一个辅助宏,但如果它使用了在 cmake 中不存在的宏而没有引用它们,那么这个答案就不太可靠了... - Chris Morgan
@ChrisMorgan 是的,你说得对。这是我犯的一个愚蠢的复制/粘贴错误。SET_COMPILE_FLAG是我在项目中编写的一个宏,在执行“SET”之前会做一些额外的工作。我已经将代码更改为“SET”。当时我回答这个问题可能已经很晚了(我甚至还有那个愚蠢的关于SET_COMPILE_FLAG的注释!)。 - SethMMorton

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接