0

I want to add unit tests to my project with FetchContent_Declare.

I have an example test like:

#include <gtest/gtest.h>

int main(int argc, char** argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

TEST(Example, One)
{
    ASSERT_TRUE(true);
}

I configure and build my tests using a CMakeLists.txt file:

cmake_minimum_required(VERSION 3.26)
project(unittest_test)

include(FetchContent)

FetchContent_Declare(
  googletest
  GIT_REPOSITORY https://github.com/google/googletest.git
  GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
  SYSTEM
)

FetchContent_MakeAvailable(googletest)

set(CMAKE_CXX_STANDARD 17)

enable_testing()

file(GLOB_RECURSE unittests_src CONFIGURE_DEPENDS "*.cpp")

set(CMAKE_COMPILE_WARNING_AS_ERROR OFF)
set_target_properties(gtest gtest_main PROPERTIES COMPILE_WARING_AS_ERROR OFF)

add_executable(
    unittests
    ${unittests_src}
)

target_link_libraries(
    unittests
    PUBLIC
    gtest
    gtest_main
)

add_test(
    NAME
    unittests
    COMMAND
    ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/unit_tests
)

I have set to use SYSTEM headers in FetchContent_Declare and turned of COMPILE_WARNING_AS_ERROR however, my project wont build because it is still setting warnings as errors:

CMake configure output:

[proc] Executing command: /usr/local/bin/cmake --version
[proc] Executing command: /usr/bin/gcc -v
[proc] The command: ninja --version failed with error: Error: spawn ninja ENOENT
[proc] The command: ninja-build --version failed with error: Error: spawn ninja-build ENOENT
[main] Configuring project: CMakeGTest 
[proc] Executing command: /usr/local/bin/cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++ -S/home/tom/src/CMakeGTest -B/home/tom/src/CMakeGTest/build -G "Unix Makefiles"
[cmake] Not searching for unused variables given on the command line.
[cmake] -- The C compiler identification is GNU 11.3.0
[cmake] -- The CXX compiler identification is GNU 11.3.0
[cmake] -- Detecting C compiler ABI info
[cmake] -- Detecting C compiler ABI info - done
[cmake] -- Check for working C compiler: /usr/bin/gcc - skipped
[cmake] -- Detecting C compile features
[cmake] -- Detecting C compile features - done
[cmake] -- Detecting CXX compiler ABI info
[cmake] -- Detecting CXX compiler ABI info - done
[cmake] -- Check for working CXX compiler: /usr/bin/g++ - skipped
[cmake] -- Detecting CXX compile features
[cmake] -- Detecting CXX compile features - done

and CMake Build output:

[main] Building folder: CMakeGTest 
[build] Starting build
[proc] Executing command: /usr/local/bin/cmake --build /home/tom/src/CMakeGTest/build --config Debug --target all -j 22 --
[build] [  8%] Building CXX object _deps/googletest-build/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o
[build] In file included from /home/tom/src/CMakeGTest/build/_deps/googletest-src/googletest/src/gtest-all.cc:42:
[build] /home/tom/src/CMakeGTest/build/_deps/googletest-src/googletest/src/gtest-death-test.cc: In function ‘bool testing::internal::StackGrowsDown()’:
[build] /home/tom/src/CMakeGTest/build/_deps/googletest-src/googletest/src/gtest-death-test.cc:1301:24: error: ‘dummy’ may be used uninitialized [-Werror=maybe-uninitialized]
[build]  1301 |   StackLowerThanAddress(&dummy, &result);
[build]       |   ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
[build] /home/tom/src/CMakeGTest/build/_deps/googletest-src/googletest/src/gtest-death-test.cc:1290:13: note: by argument 1 of type ‘const void*’ to ‘void testing::internal::StackLowerThanAddress(const void*, bool*)’ declared here
[build]  1290 | static void StackLowerThanAddress(const void* ptr, bool* result) {
[build]       |             ^~~~~~~~~~~~~~~~~~~~~
[build] /home/tom/src/CMakeGTest/build/_deps/googletest-src/googletest/src/gtest-death-test.cc:1299:7: note: ‘dummy’ declared here
[build]  1299 |   int dummy;
[build]       |       ^~~~~
[build] cc1plus: all warnings being treated as errors
[build] gmake[2]: *** [_deps/googletest-build/googletest/CMakeFiles/gtest.dir/build.make:76: _deps/googletest-build/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o] Error 1
[build] gmake[1]: *** [CMakeFiles/Makefile2:216: _deps/googletest-build/googletest/CMakeFiles/gtest.dir/all] Error 2
[build] gmake: *** [Makefile:146: all] Error 2
[proc] The command: /usr/local/bin/cmake --build /home/tom/src/CMakeGTest/build --config Debug --target all -j 22 -- exited with code: 2
[build] Build finished with exit code 2

My compiler is GCC 11.3.0 x86_64-linux-gnu

My CMake version 3.26.0-rc1

Tom McLean
  • 5,583
  • 1
  • 11
  • 36
  • Also, note on `file(GLOB)`: [official docs discourage its usage to specify target sources](https://cmake.org/cmake/help/latest/command/file.html#glob), and so do experts on Stack Overflow: see [this](/q/1027247/11107541) and [this](/q/32411963/11107541). – starball Feb 08 '23 at 19:33
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/251737/discussion-between-user-and-tom-mclean). – starball Feb 08 '23 at 21:35

1 Answers1

2

It looks like you have the same problem as the one in this issue on the googletest GitHub repo: Compile error in 1.10.0 while using GCC 11 #3219: You're using GCC 11 and googletest v1.10. That issue got fixed by this PR: https://github.com/google/googletest/pull/3024, and is available in v1.11.0.

You can workaround the issue by inhibiting warnings for the gtest target with target_compile_options(gtest PRIVATE "-w"). In GCC and other compilers, -W inhibits all warnings and the last warning-related compile flag overrides other related ones, so it overrides all warning flags to inhibit them for the gtest target.

Or if you're allowed by whoever leads your project to upgrade the version of googletest you use, just ugrade to version 1.11 or higher. (Update the GIT_TAG argument of your FetchContent_Declare call). Note that the naming convention of their git tags is a little wonky in this version range due to a convention change.


For more general cases of trying to disable warnings that get turned into errors,

Use the COMPILE_WARNING_AS_ERROR target property to specify whether warnings should be errors instead of using -Werror. It's cross platform, and you can control it per target. You can set a default value using the corresponding CMake variable, and then override the default on the test target to turn it off just for that target. If you go this route, you'll still get warnings, but they won't be errors.

See the docs for set_target_properties() and set_property() for how to set target properties.

In cases where the error / warning comes from usage of a library (and not from building the library itself), what you probably really want is to make the include directories for what you fetch using FetchContent to be treated as SYSTEM headers. If that's the case, see Is there a way to get -isystem for FetchContent targets?.

starball
  • 20,030
  • 7
  • 43
  • 238