首页 > 解决方案 > 我可以阻止 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的构建脚本修改该全局变量?或者也许已经恢复了?

标签: cmakec++17googletest

解决方案


Google Test 项目为其目标 (gtestgtest_main) 指定它们需要至少使用C++11 功能进行编译。这是通过target_compile_features命令(googletest/cmake/internal_utils.cmake#L193)完成的:

target_compile_features(${name} PUBLIC cxx_std_11)

因此,每当您链接gtestgtest_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?


推荐阅读