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

Build and use GTest globally in a project

本文关键字:GTest 构建 项目 全局      更新时间:2023-10-16

首先,我需要声明我一直在浏览Stack Overflow,并得出如何使用ExternalProject在项目中构建Google测试的答案,例如在这里。

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

+-- 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测试,然后使用这些库在其相应的文件夹中构建每个单独的测试。目前,我只能在每个子文件夹中下载构建链接一组全新的GTest库Test1, Test2, Test3这是非常低效的。有没有其他方法可以解决这个问题?

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

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

我的方法是在测试项目的同一级别创建一个目录:

+-- 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
|        ...

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

对我有用,我只构建了一次 gtest,因此所有测试项目都可以链接到它。但我会尝试尝试一下 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)