# Better way to work by modules with CMake and GTest or any library.

**URL:** https://discourse.cmake.org/t/better-way-to-work-by-modules-with-cmake-and-gtest-or-any-library/3699
**Category:** Usage
**Tags:** os:windows, comp:msvc
**Created:** [July 6, 2021, 1:09pm UTC](https://discourse.cmake.org/t/better-way-to-work-by-modules-with-cmake-and-gtest-or-any-library/3699 "2021-07-06T13:09:26Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![xhustango](https://discourse.cmake.org/user_avatar/discourse.cmake.org/xhustango/32/1614_2.png) [@xhustango](https://discourse.cmake.org/u/xhustango)
#### Post date: [July 6, 2021, 1:09pm UTC](https://discourse.cmake.org/t/better-way-to-work-by-modules-with-cmake-and-gtest-or-any-library/3699/1 "2021-07-06T13:09:26Z")

</div>

Hey there,

I am finding myself stuck to integrate some libraries of my own that are using CMake into a product. I am integrating this into the main project.

The different structure of the libraries is the following:

LIB\_A:

```auto
+-- include/
| +-- header files 
+--src
| +-- source files
+-- test
| +-- test source files
| +-- CMakeLists.txt // where I fetch GoogleTest and a JSON library for testing purposes
+-- CMakeLists.txt // where I created the lib and enable testing adding the test subdirectory

```

And that structure is followed for the rest of the libraries I have, which are around 5, for different devices like cameras, sensors, and stuff.

I am using git submodules in the main project to include my libraries, and I am adding them with  
add\_subdirectory(3rdparty/LIB\_A)

I am also fetching Google Test for testing purposes in the main project, mainly integration of each library with the rest of the components or with other specific features of the product. The issue I having is that Google Test is being already detected when fetching it in the main project.

How can I avoid this? The issue is that each library is using it. I could install GTest in the system but my manager, for some reason, does not want that approach.

Best regards

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [July 7, 2021, 12:32am UTC](https://discourse.cmake.org/t/better-way-to-work-by-modules-with-cmake-and-gtest-or-any-library/3699/2 "2021-07-07T00:32:11Z")

</div>

Take a look at the [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) module. It uses GoogleTest as one of its examples. It’s not the only way to bring it into your build, but I’ve found it to be one of the easiest.

---

<div class="post-metadata">

### Author: ![xhustango](https://discourse.cmake.org/user_avatar/discourse.cmake.org/xhustango/32/1614_2.png) [@xhustango](https://discourse.cmake.org/u/xhustango)
#### Post date: [July 7, 2021, 7:49am UTC](https://discourse.cmake.org/t/better-way-to-work-by-modules-with-cmake-and-gtest-or-any-library/3699/3 "2021-07-07T07:49:44Z")

</div>

Hi Craig,

I found that’s the way to go as well. I am not having an issue with how the module FetchContent works.  
My submodule CMake its as follows:

```auto
message(STATUS "Fetching googletest")
include(FetchContent)

FetchContent_Declare(
        googletest
        GIT_REPOSITORY https://github.com/google/googletest.git
        GIT_TAG release-1.11.0
        GIT_SHALLOW TRUE
        GIT_PROGRESS TRUE)
FetchContent_MakeAvailable(googletest)

message(STATUS "Fetching JSON library")
set(JSON_BuildTests OFF CACHE INTERNAL "")
FetchContent_Declare(
        json
        GIT_REPOSITORY https://github.com/nlohmann/json
        GIT_TAG v3.9.1
        GIT_SHALLOW TRUE
        GIT_PROGRESS TRUE)
FetchContent_MakeAvailable(json)

set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

add_executable(XUnitTes X1UnitTest.cpp X2UnitTest.cpp X3UnitTesting.cpp)
target_link_libraries(xUnitTest gtest_main MOTOR nlohmann_json::nlohmann_json)

```

and it works like a charm 😀

The problem comes when I am adding the submodule to my main project where I use Google Test for testing as well. GoogleTest is being detected in _ **build-debug/\_deps/googletest-src** _ already when CMake runs the fetching from the submodule.

This is the CMake file for testing in my main project.

```auto
include(CTest)
include(FetchContent)

FetchContent_Declare(
        googletest
        GIT_REPOSITORY https://github.com/google/googletest.git
        GIT_TAG release-1.11.0
        GIT_SHALLOW TRUE
        GIT_PROGRESS TRUE)
FetchContent_MakeAvailable(googletest)

set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
add_executable(PlaceHolderUnitTest PlaceHolderUnitTest.cpp)

target_link_libraries(PlaceHolderUnitTest gtest_main)

```

I don’t see how I can tell CMake to build GTest in another module. Should I use FetchContent\_Populate instead of FetchContent\_MakeAvailable?

Edit: As I mentioned in the post, the submodules are being added with git submodule, not with the FetchContent module.

Edit2: I guess the correct way of doing if gtest was populated already is with FetchContent\_Populate. If this works I will post the final CMakeLists.txt.

Best regards,  
Xhustango.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [July 7, 2021, 10:21pm UTC](https://discourse.cmake.org/t/better-way-to-work-by-modules-with-cmake-and-gtest-or-any-library/3699/4 "2021-07-07T22:21:38Z")

</div>

I don’t understand why the distinction between the submodules and main project. If you are adding the submodules to the main project using `add_subdirectory()`, then the whole thing is one project and it should all share the same GoogleTest instance.

Use `FetchContent_MakeAvailable()` and avoid calling `FetchContent_Populate()` if you can. The latter should only be needed in unusual situations. The `FetchContent_MakeAvailable()` was added later and should be the preferred method for most situations now.

---

<div class="post-metadata">

### Author: ![xhustango](https://discourse.cmake.org/user_avatar/discourse.cmake.org/xhustango/32/1614_2.png) [@xhustango](https://discourse.cmake.org/u/xhustango)
#### Post date: [July 12, 2021, 7:38am UTC](https://discourse.cmake.org/t/better-way-to-work-by-modules-with-cmake-and-gtest-or-any-library/3699/5 "2021-07-12T07:38:48Z")

</div>

I am mentioning the distinction because when using my ModuleA which is a library into the ProjectA which is using GTest as well and I was getting an error (Google Test was fetched previously when fetching in the ProjectA) that I am not having at the moment.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [July 13, 2021, 12:05am UTC](https://discourse.cmake.org/t/better-way-to-work-by-modules-with-cmake-and-gtest-or-any-library/3699/6 "2021-07-13T00:05:08Z")

</div>

I must be missing something about the way your project is structured. Can you put together a complete, minimal project which demonstrates the issue you are running into? That should make the problem clearer.

---

<div class="post-metadata">

### Author: ![xhustango](https://discourse.cmake.org/user_avatar/discourse.cmake.org/xhustango/32/1614_2.png) [@xhustango](https://discourse.cmake.org/u/xhustango)
#### Post date: [July 16, 2021, 9:57am UTC](https://discourse.cmake.org/t/better-way-to-work-by-modules-with-cmake-and-gtest-or-any-library/3699/7 "2021-07-16T09:57:17Z")

</div>

The structure is as follows:

```auto
+-- 3rdparty/
| +-- LibA // contains fetching gtest and json to read config files
| +-- LibB/ // contains fetching gtest
| +-- LibC/ // contains fetching gtest
+-- ProjectA
| +-- include/
| | +-- header files 
| +--src
| | +-- source files
| +-- test
| | +-- test source files
| | +-- CMakeLists.txt // It was containing ExternalProject_Add for get GTest to build the test binaries.
| +-- CMakeLists.txt // Building projectA
+-- CMakeLists.txt // main CMake where I do add_subdirectory(ProjectA); add_subdirectory(LibA)

```

The error I was getting it was related to using the external project module of CMake that was realizing that the GoogleTest was already fetched at the project level. Changing the external project module to use the FetchingContent did the trick. All this is was coming from a previous configuration where ExternalProject\_Add was being used.

So FetchContent fixes the issue, and as well I even removed it from there because there is no need anymore to fetch as its coming from one of the libraries I built.
