cmake - Global linker flag setting (for all targets in directory)(cmake - 全局链接器标志设置(用于目录中的所有目标))
问题描述
我想将链接器标志传递给我项目中的所有子项目(子目录 CMakeList).
I want to pass linker flags to all sub-projects (sub-directory CMakeList) in my project.
在切换到新的 cmake 3.3 之前,我使用了以下运行良好的代码 (cmake 3.2),为编译和链接添加了标志:
Before switching to new cmake 3.3, I was using the following code (cmake 3.2) which was working well, adding flags for both compilation and linking :
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 语法:
With cmake 3.3 this no longer works and set the flags only for compilation step. I updated the CMakeList to use a more "modern" cmake syntax :
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_libraries
命令在目标基础上添加链接器标志,但找不到其他任何东西.
This set compilation flags for all sub-projects, is there a similar way of doing this for linker flags ? I know one can add linker flags on a target basis with target_link_libraries
command but can't find anything else.
我尝试使用 CMAKE_SHARED_LINKER_FLAGS
(以及 exe、模块等的相应 var)变量但没有成功.
I tried using CMAKE_SHARED_LINKER_FLAGS
(and corresponding var for exe, module,..) variable with no success.
更新:
事实证明,这与 cmake 版本无关,除了第一个 make 命令外,CMAKE_CXX_FLAGS_XXX
变量可以正常工作.如果第二次运行 make
(在 CmakeList 中进行了修改),就会出现标志.
It turns out that this has nothing to do with cmake version, things work correctly with CMAKE_CXX_FLAGS_XXX
variables, except on first make command. If one run make
a second time (with a modification in CmakeList), flags are presents.
我想我在使用简单的 CMakeList 进行测试时找到了一个解决方案:如果在 project
命令之后声明了标志,它就会按预期工作.我不知道这是 cmake 本身的要求还是只是一种奇怪的行为.
I think I found a solution while testing with a simple CMakeList : if flags are declared after the project
command it just work as expected. I don't know if it's a requirement from cmake itself or just a weird behavior.
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 .
推荐答案
您的问题与特定的 CMake 版本无关.
Your problems are/were not related to a specific CMake version.
CMake 中的所有链接器/编译器标志变量都是一样的.因为这些变量是缓存变量并使用 project()
/enable_language()
命令设置(详情请参阅 这里),你要么必须
It's the same for all linker/compiler flag variables in CMake. Because those variables are cached variables and set with the project()
/enable_language()
command (details see here), you either have to
- 在
project()
命令之前用set(... CACHE ...)
预填充缓存 - 一般使用
set(... CACHE ... FORCE)
来强制/覆盖 - 将
set()
移动到project()
命令之后以隐藏或附加到缓存的变量
- prefill the cache with
set(... CACHE ...)
before theproject()
command - generally use the
set(... CACHE ... FORCE)
to force/overwrite - move the
set()
after theproject()
command to hide or append to the cached variables
以下是 CMAKE_EXE_LINKER_FLAGS
的示例,显示了所有三个变体:
Here is an example for CMAKE_EXE_LINKER_FLAGS
showing all three variants:
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
# 1. prefill
#set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map" CACHE INTERNAL "")
project(Test_Project CXX)
# 2. force
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map" CACHE INTERNAL "" FORCE)
# 3. hide
#set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map")
# 3. or append
#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=output.map")
# TODO: Remove, this is just for testing
file(WRITE "foo.cpp" "int main() {}")
add_executable(${PROJECT_NAME} foo.cpp)
无论这些变量的值在您的任何给定 CMakeLists.txt
文件的末尾是什么,都将应用于同一 CMakeLists.txt
文件中的所有相应目标默认值(请参阅 CMAKE - 为库设置编译标志 和 设置和使用变量的 CMake 语法是什么?).
Whatever the values of those variables are at the end of your any given CMakeLists.txt
file will be applied to all corresponding targets in the same CMakeLists.txt
file as defaults (see CMAKE - setting compile flags for libraries and What's the CMake syntax to set and use variables?).
第一个变体的缺点是它实际上只是初始值.第二个和第三个变体很可能需要一个 if (CMAKE_COMPILER_IS_GNUCXX)
围绕它,所以我更喜欢第二个变体,将这些设置移动到它自己的初始缓存文件中:
The first variant has the disadvantage that it's really only the initial value. The second and third variant would most likely need an if (CMAKE_COMPILER_IS_GNUCXX)
around it, so I prefer the second variant with moving those settings to its own initial-cache file:
MyGNUSettings.cmake
set(CMAKE_CXX_FLAGS "-stdlib=libstdc++ -Wfatal-errors" CACHE INTERNAL "" FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "-g" CACHE INTERNAL "" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "-O3" CACHE INTERNAL "" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-Map=output.map" CACHE INTERNAL "" FORCE)
使用例如
cmake -G "Unix Makefiles" -C MyGNUSettings.cmake -DCMAKE_BUILD_TYPE=Release .
是的 - 对于全局和每个编译器设置 - 我更喜欢全局缓存变量而不是 add_compile_options()
命令.我认为 add_compile_options()
并没有替换全局变量,它主要是为了防止人们将编译器选项放在 add_definitions()
命令.
And yes - for the global and per compiler settings - I prefer the global cached variables over the add_compile_options()
command. I think add_compile_options()
haven't replaced the global variables, it was mainly introduced to prevent people putting compiler options in add_definitions()
commands.
这篇关于cmake - 全局链接器标志设置(用于目录中的所有目标)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:cmake - 全局链接器标志设置(用于目录中的所有目标)
基础教程推荐
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01