【问题标题】:CMAKE separate Linker and Compiler FlagsCMAKE 单独的链接器和编译器标志
【发布时间】:2013-05-16 12:57:06
【问题描述】:

现在我的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 是我正在使用的链接器的名称(富士通)。

【问题讨论】:

  • 这里的答案似乎需要项目特定的设置。我有同样的一般问题,我不想在我尝试构建的十几个库和二进制文件中重复这些设置。
  • 嗨,我投了赞成票。我面临着同样的问题。我唯一的问题是,您有项目特定的设置。如果您可以发布 ${LD_FLAGS_STR} 是什么以及 是什么,那就太好了。因为我还想减少/删除代码中未使用的部分

标签: eclipse cmake


【解决方案1】:

尝试使用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 编译和链接就没有问题,但是 fujitsu 编译器和链接器是完全不同的(带有不同的标志)!!
  • 它真的很令人沮丧,没有关于 cmake 的好的文档:(
  • 在回复您的第一条评论时,如果您不使用SET_COMPILE_FLAG,您可以尝试将COMPILE_FLAGS 选项改为SET_TARGET_PROPERTIES。这可能会让您真正区分编译器和链接器。
  • 这个 SET_COMPILE_FLAG() 是什么?它不在 cmake 文档中,我在使用它时会报告错误。我确实找到了类似 SET_COMPILE_FLAGS 的东西,一个辅助宏,但是如果它使用 cmake 中不存在的宏而不引用它们,那么这个答案并不可靠......
  • @ChrisMorgan 是的,你是对的。这是我的一个愚蠢的复制/粘贴错误。 SET_COMPILE_FLAG 是我在我的项目中编写的一个宏,它在做SET 之前做了一些额外的工作。我将代码更改为SET。我写这个答案的时候一定已经很晚了(我什至有关于 SET_COMPILE_FLAG 的愚蠢注释!)。
【解决方案2】:

对于较新版本的 cmake,使用生成器表达式 [1] 是我的首选方法。

target_compile_options(${TARGET_NAME}
    PRIVATE
        $<$<COMPILE_LANGUAGE:C>:${C_DEFS} ${C_FLAGS}>
        $<$<COMPILE_LANGUAGE:ASM>:${ASM_FLAGS}>)

[1]https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    相关资源
    最近更新 更多