【问题标题】:Turning on linker flags with CMake使用 CMake 打开链接器标志
【发布时间】:2011-04-02 10:27:37
【问题描述】:
当使用 CMake 生成 VS2010 目标时,我希望打开 /LTCG 标志(如果可能,仅用于 release + releasewithdebinfo,但如果它打开用于调试构建也可以)。如何修改链接器标志? add_definitions() 不起作用,因为它只会修改编译器标志。是的,我已经将它包装在 if(MSVC) 中。
如何修改链接器标志?
【问题讨论】:
标签:
c++
c
visual-studio-2010
linker
cmake
【解决方案1】:
您可以使用 #pragma comment(linker, ...) 修改 MSC 中的链接器标志
但是,如果您想在构建过程中使用 cmake 进行此操作,则需要知道以下名称:
CMAKE_EXE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS
(感谢Cmake.org)。
【解决方案3】:
使用“ucm”库似乎是一个不错的方法。我推出了一个简单的宏,它可以帮助我在 CMake 中为所有配置统一管理链接器标志,同时还允许特定于编译器的使用。 (当 CMake 被多次配置时,仅仅设置变量会导致标志堆积。)
macro(ADD_MSVC_LINKER_FLAG flag)
if(MSVC)
if(${CMAKE_EXE_LINKER_FLAGS} MATCHES "(${flag}.*)")
# message("skipping linker flags")
else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${flag}" CACHE STRING "Linker Flags for Release Builds" FORCE)
endif()
if(${CMAKE_SHARED_LINKER_FLAGS} MATCHES "(${flag}.*)")
# message("skipping linker flags")
else()
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${flag}" CACHE STRING "Linker Flags for Release Builds" FORCE)
endif()
if(${CMAKE_STATIC_LINKER_FLAGS} MATCHES "(${flag}.*)")
# message("skipping linker flags")
else()
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${flag}" CACHE STRING "Linker Flags for Release Builds" FORCE)
endif()
if(${CMAKE_MODULE_LINKER_FLAGS} MATCHES "(${flag}.*)")
# message("skipping linker flags")
else()
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${flag}" CACHE STRING "Linker Flags for Release Builds" FORCE)
endif()
endif()
endmacro()
然后通过创建特定于编译器的宏来支持其他编译器,该宏会检查正在使用的编译器。这使得在错误的编译器上设置正确的标志变得更加困难。
if(CMAKE_COMPILER_IS_GNUCXX)
和
if(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang)
【解决方案4】:
用于添加链接器标志 - 以下 4 个 CMake 变量:
CMAKE_EXE_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS
CMAKE_STATIC_LINKER_FLAGS
可以使用ucm 的ucm_add_linker_flags 宏轻松操作不同的配置(调试、发布...)
链接器标志也可以基于每个目标进行管理 - 通过使用target_link_libraries 并在它们前面传递带有- 的标志(但不能使用-l - 这将被视为链接库而不是链接标志)。
【解决方案5】:
您可以使用LINK_FLAGS 属性为特定目标添加链接器标志:
set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${flag}")
(请注意,由于我使用的是APPEND_STRING,所以我在标志前添加了一个空格)