0

My C++ project is built with CMake and includes tests utilizing GoogleTest. In order to keep me from compatibility issues between different projects and the installed/compiled GoogleTest version, I once decided to have GoogleTest always local in my project directories.

I achieved this by having GoogleTest downloaded and built as part of my own test project, that includes/links gtest. This looks like this in the respective 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"
)

In order to have this working there is an external project defined in 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 ""
)

So far so good!

This worked quite a while for me, but I run into some trouble, since I started to use C++17 features in my most recent project. This is a problem because my test project refuses to compile, when it includes code, that makes use of C++17.

The reason for this is, that running GoogleTest's CMake build modifies the CMAKE_CXX_FLAGS variable on a global scale. In fact it overrides my definition of the compiler mode:

CXX_FLAGS =  -Wall -pedantic -std=c++17   -std=gnu++11

... where it should look like this:

CXX_FLAGS =  -Wall -pedantic -std=c++17

Is there a way to keep GoogleTest's build script from modifying that global variable? Or maybe have it restored?

salchint
  • 371
  • 3
  • 10

1 Answers1

0

Google Test project specifies for its targets (gtest and gtest_main) that they need to be compiled with at least C++11 features. This is done with target_compile_features command (googletest/cmake/internal_utils.cmake#L193):

target_compile_features(${name} PUBLIC cxx_std_11)

So, whenever you link with gtest or gtest_main targets, CMake checks, whether C++11 is already provided by the caller, and if no, adds corresponded compiler flag (-std=gnu++11 for gcc).

It seems you have added -std=c++17 directly into CMAKE_CXX_FLAGS variable. This is a bad way for specify the standard: CMake never checks CMAKE_CXX_FLAGS for detect which compiler features are currently enabled.

The correct setting of c++17 implies either setting CMAKE_CXX_STANDARD variable:

set(CMAKE_CXX_STANDARD 17)

or calling target_compile_features for your targets:

target_compile_features(my_exe PUBLIC cxx_std_17)

See more about setting C/C++ standard in CMake in that question: How do I activate C++ 11 in CMake?

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153