【发布时间】:2015-09-21 15:05:11
【问题描述】:
我想将链接器标志传递给我项目中的所有子项目(子目录 CMakeList)。
在切换到新的 cmake 3.3 之前,我使用了以下运行良好的代码 (cmake 3.2),为编译和链接添加了标志:
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -stdlibc++")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -stdlibc++")
在 cmake 3.3 中,这不再有效,并且仅为编译步骤设置标志。我更新了 CMakeList 以使用更“现代”的 cmake 语法:
set(MY_DEBUG_OPTIONS -g -stdlib=libstdc++ -Wfatal-errors)
set(MY_RELEASE_OPTIONS -O3 -stdlib=libstdc++ -Wfatal-errors)
add_compile_options(
"$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>"
"$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")
这为所有子项目设置编译标志,是否有类似的方法为链接器标志执行此操作?我知道可以使用target_link_librariescommand 在目标基础上添加链接器标志,但找不到其他任何东西。
我尝试使用 CMAKE_SHARED_LINKER_FLAGS(以及 exe、模块等对应的 var)变量但没有成功。
更新:
事实证明,这与 cmake 版本无关,除了第一个 make 命令外,CMAKE_CXX_FLAGS_XXXvariables 可以正常工作。如果第二次运行make(在 CmakeList 中进行了修改),则会出现标志。
我想我在使用简单的 CMakeList 进行测试时找到了一个解决方案:如果在 project 命令之后声明了标志,它就会按预期工作。我不知道这是 cmake 本身的要求还是只是一种奇怪的行为。
cmake_minimum_required (VERSION 3.2)
set(PROJECT Test_Project)
# Not working (on first run)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -stdlib=libstdc++ -Wfatal-errors")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -stdlib=libstdc++ -Wfatal-errors")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -stdlib=libstdc++ -Wfatal-errors")
project(${PROJECT})
# Declare here instead...
add_executable(Test test.cpp)
MESSAGE( STATUS "Config flags : " ${CMAKE_CXX_FLAGS_RELEASE})
使用:
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release .
【问题讨论】:
-
我想知道为什么您的第一种方法应该停止使用
CMake3.3。所以我检查了CMakeCXXInformation.cmake中的CMAKE_CXX_LINK_EXECUTABLE和CMAKE_CXX_CREATE_SHARED_LIBRARY之类的代码更改。但是没有什么明显的,所以你能否在你的目标 make 环境中添加一些细节?看起来像GNU,但是你用的是什么版本/口味/操作系统? -
你是对的,我错了,cmake 3.2 也有问题。我做了一个非常简单的“Hello world”项目,问题是:我第一次在
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release .之后运行make,除了cmake 默认标志(例如-O3、-DNDEBUG 用于发布构建)之外没有其他标志。然后,如果我更新 CMakeList 文件(例如,在标志字符串中添加一个空格),cmake 现在会正确添加所有标志。 (在带有 xcode 工具链的 os x yosemite 上) -
好的,那么这与CMake cross-compiling: C flags from toolchain file ignored 的问题相同。有关一些背景信息,请参阅my answer there。简而言之,只需将变量
set()命令放在project()命令之后即可。 -
是的,这就是我最终要做的。感谢您提供背景信息!
-
不客气。我添加了一个答案来涵盖调查结果、示例代码和背景信息。