在项目中全局构建和使用 GTest

Build and use GTest globally in a project

首先,我需要声明我一直在研究 Stack Overflow 并得出如何使用 ExternalProject 在项目中构建 Google 测试的答案,例如 here .

现在让我们说我的项目是这样的

+-- CMakeLists.txt (the big CMake File for the entire project)
+-- tests
|    +-- CMakeLists.txt (contain of all the small project in the tests)
|    +-- Test1
|        +-- CMakeLists.txt (test file for Test1 program)
|        +-- test_1.cpp
|        +-- test_1.h
|    +-- Test2
|        +-- CMakeLists.txt (test file for Test2 program)
|        +-- test_2.cpp
|        +-- test_2.h
|    +-- Test3
|        +-- CMakeLists.txt (test file for Test3 program)
|        +-- test_3.cpp
|        +-- test_3.h

现在,我是否可以在 CMakeLists.txt 大文件(位于根文件夹)中使用 ExternalProject 配置和构建 Google 测试,然后使用这些库来在相应的文件夹中构建每个单独的测试。目前,我只能在每个子文件夹 Test1, Test2, Test3 中下载内置的 link 一整套新的 GTest 库,这是非常低效的。有其他方法可以解决这个问题吗?

如果不查看您的实际 CMakeLists.txt 文件,就不清楚您的情况。也就是说,以正常方式使用,ExternalProject 不会直接为您提供 link 的 CMake 目标,您必须做更多的手动工作才能获得可以添加到 linked 库列表中的内容您的目标需要使用 GTest。因此,根据您手动定义这些内容的方式,这可能就是您发现需要在每个 TestX 子目录中构建 GTest 的原因。

在您 linked 的另一个 SO 问题中,my answer there 和其中的 linked 文章提到了如何下载和构建 GTest 作为 CMake 阶段的一部分而不是在构建时间。这为您提供了 CMake 目标,然后您可以 link 直接针对这些目标而无需手动定义它们。如果您按照该方法在顶级 CMakeLists.txt 文件中下载并构建 GTest,那么 gtestgtest main 目标将对所有子目录可见。此外,您不必为每个平台找出库的名称等,因为 CMake 目标已经为您处理了。因此,在您的各种 Test1、Test2 和 Test3 子目录中,您所要做的就是将 gtestgtest_main 添加到每个测试程序 link 反对的库列表中。

我的做法是在你的测试项目的同一层创建一个目录:

+-- CMakeLists.txt (the big CMake File for the entire project)
+-- tests
|    +-- CMakeLists.txt (contain of all the small project in the tests)
|    +-- gtest
|        +-- CMakeLists.txt (use ExternalProject_Add to import GTest)
|    +-- Test1
|        +-- CMakeLists.txt (test file for Test1 program)
|        +-- test_1.cpp
|        +-- test_1.h
|    +-- Test2
|        ...

gtestCMakeLists.txt 中,我定义了 gtest 目标并导出包含目录和库路径的变量以供其他项目使用。

它对我有用,我只构建了一次 gtest,因此所有测试项目都可以 link 反对它。但我会尝试介绍 Craig Scott 在 Makefile 生成期间而不是在构建时构建 gtest 的方法。

gtest文件夹下的CMakeLists.txt文件如下所示:

cmake_minimum_required(VERSION 2.8.11)

include(ExternalProject)

set(GMOCK_VERSION "1.7.0")
set(GMOCK_DIR "${CMAKE_CURRENT_BINARY_DIR}/gmock-${GMOCK_VERSION}")
ExternalProject_Add(project_gmock
    SVN_REPOSITORY http://googlemock.googlecode.com/svn/tags/release-${GMOCK_VERSION}
    PREFIX ${GMOCK_DIR}
    CMAKE_ARGS -DCMAKE_C_COMPILER:PATH=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER}
    # Disable update step
    UPDATE_COMMAND ""
    # Disable install step
    INSTALL_COMMAND ""
)
ExternalProject_Get_Property(project_gmock source_dir)
ExternalProject_Get_Property(project_gmock binary_dir)

include_directories(${source_dir}/gtest/include)
add_library(gtest STATIC IMPORTED GLOBAL)
set_target_properties(gtest PROPERTIES IMPORTED_LOCATION ${binary_dir}/gtest/libgtest.a)
set_target_properties(gtest PROPERTIES INCLUDE_DIRECTORIES ${source_dir}/gtest/include)
add_dependencies(gtest project_gmock)
get_property(GTEST_INCLUDE_DIR TARGET gtest PROPERTY INCLUDE_DIRECTORIES)
set(GTEST_INCLUDE_DIR "${GTEST_INCLUDE_DIR}" PARENT_SCOPE)

add_library(gtest_main STATIC IMPORTED GLOBAL)
set_target_properties(gtest_main PROPERTIES IMPORTED_LOCATION ${binary_dir}/gtest/libgtest_main.a)
add_dependencies(gtest_main project_gmock)

include_directories(${source_dir}/include)
add_library(gmock STATIC IMPORTED GLOBAL)
set_target_properties(gmock PROPERTIES IMPORTED_LOCATION ${binary_dir}/libgmock.a)
set_target_properties(gmock PROPERTIES INCLUDE_DIRECTORIES ${source_dir}/include)
add_dependencies(gmock project_gmock)
get_property(GMOCK_INCLUDE_DIR TARGET gmock PROPERTY INCLUDE_DIRECTORIES)
set(GMOCK_INCLUDE_DIR "${GMOCK_INCLUDE_DIR}" PARENT_SCOPE)

add_library(gmock_main STATIC IMPORTED GLOBAL)
set_target_properties(gmock_main PROPERTIES IMPORTED_LOCATION ${binary_dir}/libgmock_main.a)
add_dependencies(gmock_main project_gmock)