9

This is my first post on StackOverflow, so apologies if there's something wrong with my question.

I'm new at CMake, and I'm running into a problem trying to import gtest (Google Test) in a C++ project with an existing gtest directory used within a library.

My root CMakeLists.txt file is this (My changes are made between "Begin changes" and "End changes") :

cmake_minimum_required(VERSION 2.6) project(nifi-minifi-cpp) set(PROJECT_NAME "nifi-minifi-cpp") set(PROJECT_VERSION_MAJOR 0) set(PROJECT_VERSION_MINOR 2) set(PROJECT_VERSION_PATCH 0) #### Establish Project Configuration #### # Enable usage of the VERSION specifier # https://cmake.org/cmake/help/v3.0/policy/CMP0048.html#policy:CMP0048 IF(POLICY CMP0048) CMAKE_POLICY(SET CMP0048 OLD) ENDIF(POLICY CMP0048) include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) if(COMPILER_SUPPORTS_CXX11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") elseif(COMPILER_SUPPORTS_CXX0X) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") else() message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") endif() set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Search for threads find_package(Threads REQUIRED) # Provide custom modules for the project list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") add_subdirectory(thirdparty/yaml-cpp-yaml-cpp-0.5.3) add_subdirectory(libminifi) add_subdirectory(main) # Generate source assembly set(ASSEMBLY_BASE_NAME "${CMAKE_PROJECT_NAME}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") set(CPACK_SOURCE_GENERATOR "TGZ") set(CPACK_SOURCE_PACKAGE_FILE_NAME "${ASSEMBLY_BASE_NAME}-source") set(CPACK_SOURCE_IGNORE_FILES "/build/;~$;${CPACK_SOURCE_IGNORE_FILES};${CMAKE_SOURCE_DIR}/.git/;${CMAKE_SOURCE_DIR}/.idea/;${CMAKE_SOURCE_DIR}/cmake-build-debug/") # Generate binary assembly install(FILES conf/minifi.properties conf/config.yml DESTINATION conf COMPONENT bin) install(PROGRAMS bin/minifi.sh DESTINATION bin COMPONENT bin) install(FILES LICENSE README.md NOTICE DESTINATION . COMPONENT bin) set(CPACK_GENERATOR "TGZ") set(CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY 1) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Apache NiFi MiNiFi C++ version ${VERSION}") set(CPACK_PACKAGE_VENDOR "Apache NiFi") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") set(CPACK_PACKAGE_FILE_NAME "${ASSEMBLY_BASE_NAME}") set(CPACK_BINARY_TGZ, "ON") set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) set(CPACK_COMPONENTS_ALL bin) include(CPack) #### Begin changes # Set up testing enable_testing() set(GTEST_ROOT "thirdparty/googletest/googletest") add_subdirectory(thirdparty/googletest) # find_package(GTest REQUIRED) include_directories(${GTEST_INCLUDE_DIRS}) add_executable(tailFileTest test/TailFileTest.cpp ) target_link_libraries(tailFileTest ${GTEST_LIBRARY_DEBUG} ${GTEST_MAIN_LIBRARY_DEBUG}) add_test( NAME tailFileTest COMMAND tailFileTest ) #add_dependencies(${PROJECT_TEST_NAME} googletest) #set(PROJECT_TEST_NAME ${PROJECT_NAME}_test) #file(GLOB TEST_SRC_FILES ${PROJECT_SOURCE_DIR}/test/*.cpp) # #add_executable(${PROJECT_TEST_NAME} ${TEST_SRC_FILES}) #add_dependencies(${PROJECT_TEST_NAME} googletest) #### End changes 

And output from CMake when running cmake .. (the more relevant error message - probably) is:

CMake Error at thirdparty/googletest/googletest/cmake/internal_utils.cmake:151 (add_library): add_library cannot create target "gtest" because another target with the same name already exists. The existing target is a static library created in source directory "/home/dev/nifi-minifi-cpp/thirdparty/yaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest". See documentation for policy CMP0002 for more details. 

Currently, I've got a copy of googletest in:

/home/g/dev/nifi-minifi-cpp/thirdparty/googletest 

And the existing googletest directory is within:

/home/g/dev/nifi-minifi-cpp/thirdparty/yaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0 

Here's a quick picture of the directory structure:

. ├── CMakeLists.txt ├── test [<- My directory to store and run tests] └── thirdparty ├── googletest [<- My googletest directory] └── yaml-cpp-yaml-cpp-0.5.3 ├── test │   ├── CMakeLists.txt │   ├── gmock-1.7.0 [<- The existing googletest directory] 278 directories, 2096 files 

The overall goal is to have a test directory for running tests.

Any suggestions or clues to what I'm doing wrong, or what I should be doing, would be greatly appreciated. Hopefully the above explains the challenge I'm facing, and if there's a file or error message people think I'm missing that would help I can paste it in here.

1
  • Why do you have two googleTest folders (My googletest directory and The existing googletest directory) ? Is it possible that you have in the CMakeList from yaml-cpp-yaml-cpp-0.5.3 also a entry add_subdirectory(gmock-1.7.0)? This could be the problem, because of your error message said that you have multiple targets with the name gtest. Commented Feb 7, 2017 at 10:29

1 Answer 1

3

This is just double including 3d-party project (gtest in your case) using add_subdirectory. The first include point is

add_subdirectory(gmock-1.7.0) 

inside yaml-cpp subproject and the second include point is

add_subdirectory(thirdparty/googletest) 

in your CMakeLists.txt.

Such double including doesn't work in CMake, so you need to eliminate one of add_subdirectory call.

  1. In your code, you may replace add_subdirectory approach by combination of ExternalProject_Add and execute_process. That approach will build googletest on configuration stage (so, find_package(GTest) will work), but doesn't pollute namespace of your project with targets from googletest.

  2. In other project (yaml-cpp), you may eliminate including googletest by disable testing. Just disable appropriate option

    option(YAML_CPP_BUILD_TOOLS "Enable testing and parse tools" OFF) 

    before

    add_subdirectory(thirdparty/yaml-cpp-yaml-cpp-0.5.3) 

    (For disabling option from CMakeLists.txt you need to reconfigure the whole project cleanly, that is with empty CMake cache).

    Note, that this option also disables some utilities under util/ subdirectory of yaml-cpp project.

  3. Similarly to the first approach, you may change inclusion of yaml-cpp subproject to ExternalProject_Add + execute_process. Such a way all its targets and targets of its subprojects will not pollute namespace of your project.

Sign up to request clarification or add additional context in comments.

4 Comments

can you give an example for case 1? Thanks!
Hm, don't remember why ExternalProject is needed in that case. Configure gtest: execute_process(COMMAND ${CMAKE_EXECUTABLE} <gtest-source-dir> -DCMAKE_INSTALL_PREFIX=<choosen-gtest-install-dir> WORKING_DIRECTORY <choosen-gtest-build-dir>). Build and install gtest: execute_process(COMMAND ${CMAKE_EXECUTABLE} --build <choosen-gtest-build-dir> --target install).
@Tsyvarev This, unfortunately, doesn't work. It cannot find the gtest/gtest.h in the tests.
@Patrick: What exact approach doesn't work? What exact commands you use? It is better to create your own question post with all this information.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.