cmake - 我可以阻止 GoogleTest-build 修改全局 CMAKE_CXX_FLAGS 变量吗?
问题描述
我的C++项目是用CMake构建的,包括使用GoogleTest的测试。为了避免不同项目和已安装/编译的GoogleTest版本之间的兼容性问题,我曾经决定让GoogleTest始终位于我的项目目录中。
我通过将GoogleTest下载并构建为我自己的测试项目的一部分来实现这一点,其中包括/链接 gtest。这在各自中看起来像这样CMakeLists.txt
:
# Download and unpack googletest at configure time
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/googletest-download"
)
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/googletest-download"
)
为了让这个工作有一个外部项目定义在CMakeLists.txt.in
:
cmake_minimum_required(VERSION 2.8.2)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
到现在为止还挺好!
这对我来说工作了很长一段时间,但我遇到了一些麻烦,因为我在最近的项目中开始使用C++17功能。这是一个问题,因为我的测试项目在包含使用C++17的代码时拒绝编译。
这样做的原因是,运行GoogleTest的 CMake 构建会在CMAKE_CXX_FLAGS
全球范围内修改变量。事实上它覆盖了我对编译器模式的定义:
CXX_FLAGS = -Wall -pedantic -std=c++17 -std=gnu++11
...它应该看起来像这样:
CXX_FLAGS = -Wall -pedantic -std=c++17
有没有办法阻止GoogleTest的构建脚本修改该全局变量?或者也许已经恢复了?
解决方案
Google Test 项目为其目标 (gtest
和gtest_main
) 指定它们需要至少使用C++11 功能进行编译。这是通过target_compile_features
命令(googletest/cmake/internal_utils.cmake#L193)完成的:
target_compile_features(${name} PUBLIC cxx_std_11)
因此,每当您链接gtest
或gtest_main
目标时,CMake 都会检查调用者是否已经提供了 C++11,如果没有,则添加相应的编译器标志(-std=gnu++11
用于 gcc)。
看来您已-std=c++17
直接添加到CMAKE_CXX_FLAGS
变量中。这是指定标准的不好方法CMAKE_CXX_FLAGS
:CMake 从不检查当前启用了哪些编译器功能。
c++17 的正确设置意味着设置CMAKE_CXX_STANDARD
变量:
set(CMAKE_CXX_STANDARD 17)
或呼吁target_compile_features
您的目标:
target_compile_features(my_exe PUBLIC cxx_std_17)
在该问题中查看有关在 CMake 中设置 C/C++ 标准的更多信息:如何在 CMake 中激活 C++ 11?
推荐阅读
- javascript - 使用 javascript(Tampermonkey 脚本)在 React 输入中输入文本?
- r - 如何在 R 中导入 .rec 文件
- scala - 如何最有效地在scala中合并和聚合2个地图?
- python - 按类 INSTAGRAM、selenium python 复制标题
- ruby-on-rails - 短信网关的 Fedena 短信设置
- sql-server - SELECT 语句返回 DATETIME 之外的行
- python - 无法在 Python 中使用 h2o 导入文件
- awk - 如何关联数据以使用 awk 执行命令操作?
- github - GitHub 如何猜测文件的编码?
- c# - 如何打印每行打印在新页面中的datagridview?