【问题标题】:C++ project organisation (with gtest, cmake and doxygen)C++ 项目组织(使用 gtest、cmake 和 doxygen)
【发布时间】:2012-11-11 09:04:20
【问题描述】:

我一般是编程新手,所以我决定从用 C++ 制作一个简单的向量类开始。不过,我想从一开始就养成良好的习惯,而不是以后尝试修改我的工作流程。

我目前只有两个文件 vector3.hppvector3.cpp。随着我对一切的熟悉,这个项目将慢慢开始成长(使它更像是一个通用的线性代数库),所以我想采用“标准”项目布局,让以后的生活更轻松。所以环顾四周后,我发现了两种组织 hpp 和 cpp 文件的方法,第一种是:

project
└── src
    ├── vector3.hpp
    └── vector3.cpp

第二个是:

project
├── inc
│   └── project
│       └── vector3.hpp
└── src
    └── vector3.cpp

您会推荐哪个以及为什么?

其次,我想使用 Google C++ 测试框架对我的代码进行单元测试,因为它看起来相当容易使用。您是否建议将此与我的代码捆绑在一起,例如在inc/gtestcontrib/gtest 文件夹中?如果捆绑,您建议使用fuse_gtest_files.py 脚本来减少数量或文件,还是保持原样?如果没有捆绑,这个依赖如何处理?

在编写测试时,这些通常是如何组织的?我想为每个类创建一个 cpp 文件(例如 test_vector3.cpp),但都编译成一个二进制文件,以便它们可以轻松地一起运行?

由于 gtest 库通常是使用 cmake 和 make 构建的,我在想我的项目也像这样构建是否有意义?如果我决定使用以下项目布局:

├── CMakeLists.txt
├── contrib
│   └── gtest
│       ├── gtest-all.cc
│       └── gtest.h
├── docs
│   └── Doxyfile
├── inc
│   └── project
│       └── vector3.cpp
├── src
│   └── vector3.cpp
└── test
    └── test_vector3.cpp

CMakeLists.txt 的外观如何才能仅构建库或库和测试?此外,我还看到不少具有buildbin 目录的项目。构建是否发生在构建目录中,然后二进制文件移出到 bin 目录中?测试和库的二进制文件会在同一个地方吗?或者将其结构如下更有意义:

test
├── bin
├── build
└── src
    └── test_vector3.cpp

我还想使用 doxygen 来记录我的代码。是否可以使用 cmake 和 make 自动运行它?

很抱歉问了这么多问题,但我还没有找到一本关于 C++ 的书可以令人满意地回答这些类型的问题。

【问题讨论】:

  • 很好的问题,但我认为它不适合Stack Overflow 的问答形式。不过,我对答案很感兴趣。 +1 和最爱
  • 这些问题很多。最好将其拆分为几个较小的问题并相互放置链接。无论如何回答最后一部分:使用 CMake,您可以选择在 src 目录内部和外部构建(我建议在外部)。是的,您可以自动将 doxygen 与 CMake 一起使用。

标签: c++ cmake doxygen googletest


【解决方案1】:

C++ 构建系统有点玄学,而且项目越老 你能找到更多奇怪的东西,所以很多东西并不奇怪 的问题出现。我将尝试一一解决问题,并提及有关构建 C++ 库的一些一般性问题。

分隔目录中的头文件和 cpp 文件。这只是 如果您正在构建应该使用的组件,则必不可少 作为一个库而不是一个实际的应用程序。你的标题是 用户与您提供的产品进行交互的基础,并且必须是 安装。这意味着它们必须位于子目录中(没有人想要 许多标题以顶级/usr/include/) 和您的 标头必须能够在这样的设置中包含自己。

└── prj
    ├── include
    │   └── prj
    │       ├── header2.h
    │       └── header.h
    └── src
        └── x.cpp

效果很好,因为包含路径可以解决,您可以轻松使用 安装目标的通配符。

捆绑依赖:我认为这在很大程度上取决于 构建系统来定位和配置依赖关系以及如何 将您的代码依赖于单个版本。这也取决于如何 您的用户的能力以及在其上安装依赖项的难易程度 平台。 CMake 为 Google 提供了一个 find_package 脚本 测试。这使事情变得容易得多。我只会捆绑 必要时避免使用。

如何构建:避免源内构建。 CMake 使用源代码构建 容易,它让生活更轻松。

我想您还想使用 CTest 为您的系统运行测试(它 还附带了对 GTest 的内置支持)。一个重要的决定 目录布局和测试组织将是:你最终得到 子项目?如果是这样,您在设置 CMakeLists 时需要做更多的工作 并且应该将您的子项目拆分为子目录,每个子目录都有其 拥有 includesrc 文件。也许甚至他们自己的doxygen运行和 输出(组合多个 doxygen 项目是可能的,但并不容易 或漂亮)。

你会得到这样的结果:

└── prj
    ├── CMakeLists.txt <-- (1)
    ├── include
    │   └── prj
    │       ├── header2.hpp
    │       └── header.hpp
    ├── src
    │   ├── CMakeLists.txt <-- (2)
    │   └── x.cpp
    └── test
        ├── CMakeLists.txt <-- (3)
        ├── data
        │   └── testdata.yyy
        └── testcase.cpp

在哪里

  • (1) 配置依赖关系、平台细节和输出路径
  • (2) 配置你要构建的库
  • (3) 配置测试可执行文件和测试用例

如果您有子组件,我建议您添加另一个层次结构并为每个子项目使用上面的树。然后事情就变得棘手了,因为您需要决定子组件是搜索和配置它们的依赖关系,还是在顶层进行。这应根据具体情况决定。

Doxygen:在你成功完成了配置舞蹈之后 doxygen,使用 CMake add_custom_command 添加一个 文档目标。

这就是我的项目的最终结果,我见过一些非常相似的项目,但当然这不是万能的。

附录在某些时候你会想要生成一个config.hpp 包含版本定义的文件,可能还有某个版本的定义 控制标识符(Git 哈希或 SVN 修订号)。 CMake 有 自动查找该信息并生成的模块 文件。您可以使用 CMake 的 configure_file 替换变量 带有在CMakeLists.txt 中定义的变量的模板文件。

如果您正在构建库,您还需要一个导出定义以 正确区分编译器,例如__declspec 在 MSVC 上 和 GCC/clang 上的 visibility 属性。

【讨论】:

  • 不错的答案,但我仍然不清楚为什么你需要将你的头文件放在一个额外的项目命名的子目录中:“/prj/include/prj/foo.hpp”,这似乎是多余的我。为什么不只是“/prj/include/foo.hpp”?我假设您将有机会在安装时重新调整安装目录,因此您在安装时会得到 /include/prj/foo.hpp,或者在 CMake 下这很难吗?
  • @William 使用 CPack 实际上很难做到这一点。另外,您在源文件中包含的内容如何?如果它们只是已安装版本上的“header.hpp”,则“/usr/include/prj/”需要位于包含路径中,而不仅仅是“/usr/include”。
【解决方案2】:

首先,您不能忽略一些常规的目录名称,这些名称是基于 Unix 文件系统的悠久传统。它们是:

trunk
├── bin     : for all executables (applications)
├── lib     : for all other binaries (static and shared libraries (.so or .dll))
├── include : for all header files
├── src     : for source files
└── doc     : for documentation

坚持这种基本布局可能是个好主意,至少在顶层是这样。

关于拆分头文件和源文件(cpp),这两种方案都相当普遍。但是,我倾向于将它们放在一起,在日常任务中将文件放在一起更实用。此外,当所有代码都在一个顶级文件夹下时,即trunk/src/ 文件夹,您会注意到所有其他文件夹(bin、lib、include、doc,可能还有一些测试文件夹)都在顶级,除了源外构建的“构建”目录之外,所有文件夹都只包含构建过程中生成的文件。因此,只需要备份 src 文件夹,或者更好的是,将其保存在版本控制系统/服务器(如 Git 或 SVN)下。

当涉及到在目标系统上安装头文件时(如果你想最终分发你的库),CMake 有一个安装文件的命令(隐式创建一个“安装”目标,执行“make install ") 您可以使用它来将所有标题放入/usr/include/ 目录。我只是为此目的使用以下 cmake 宏:

# custom macro to register some headers as target for installation:
#  setup_headers("/path/to/header/something.h" "/relative/install/path")
macro(setup_headers HEADER_FILES HEADER_PATH)
  foreach(CURRENT_HEADER_FILE ${HEADER_FILES})
    install(FILES "${SRCROOT}${CURRENT_HEADER_FILE}" DESTINATION "${INCLUDEROOT}${HEADER_PATH}")
  endforeach(CURRENT_HEADER_FILE)
endmacro(setup_headers)

SRCROOT 是我设置到 src 文件夹的一个 cmake 变量,INCLUDEROOT 是我配置到头文件需要去的任何地方的 cmake 变量。当然,还有很多其他的方法可以做到这一点,我敢肯定我的方法不是最好的。关键是,没有理由仅仅因为只需要在目标系统上安装头文件就将头文件和源分开,因为很容易,特别是使用 CMake(或 CPack),挑选和配置头文件以无需将它们放在单独的目录中即可安装。这是我在大多数图书馆看到的。

Quote: 其次,我想使用 Google C++ 测试框架对我的代码进行单元测试,因为它看起来相当容易使用。您是否建议将此与我的代码捆绑在一起,例如在“inc/gtest”或“contrib/gtest”文件夹中?如果捆绑,您建议使用 fuse_gtest_files.py 脚本来减少数量或文件,还是保持原样?如果没有捆绑,这个依赖如何处理?

不要将依赖项与您的库捆绑在一起。这通常是一个非常可怕的想法,当我被困在试图构建一个这样做的库时,我总是讨厌它。这应该是你最后的手段,并提防陷阱。通常,人们将依赖项与他们的库捆绑在一起,要么是因为他们针对的是糟糕的开发环境(例如 Windows),要么是因为他们只支持相关库(依赖项)的旧(不推荐)版本。主要的缺陷是您的捆绑依赖项可能与同一个库/应用程序的已安装版本冲突(例如,您捆绑了 gtest,但尝试构建您的库的人已经安装了更新(或旧)版本的 gtest,然后两者可能会发生冲突并使那个人非常头疼)。所以,正如我所说,这样做需要您自担风险,我只会说作为最后的手段。要求人们在编译你的库之前安装一些依赖项比试图解决捆绑的依赖项和现有安装之间的冲突要小得多。

Quote: 在编写测试时,这些通常是如何组织的?我在想每个类都有一个 cpp 文件(例如 test_vector3.cpp),但都编译成一个二进制文件,这样它们就可以很容易地一起运行?

在我看来,每个类(或小的有凝聚力的类和函数组)一个 cpp 文件更常见和实用。但是,绝对不要将它们全部编译成一个二进制文件,以便“它们都可以一起运行”。这真是个坏主意。通常,当涉及到编码时,您希望尽可能多地拆分事物。在单元测试的情况下,您不希望一个二进制文件运行所有测试,因为这意味着您对库中的任何内容所做的任何微小更改都可能导致该单元测试程序几乎完全重新编译,而这只是等待重新编译的几分钟/几小时。只需坚持一个简单的方案:1 个单元 = 1 个单元测试程序。然后,使用脚本或单元测试框架(例如 gtest 和/或 CTest)运行所有测试程序并报告失败/成功率。

Quote: 由于gtest 库通常是使用cmake 和make 构建的,我在想我的项目也像这样构建是否有意义?如果我决定使用以下项目布局:

我宁愿建议这种布局:

trunk
├── bin
├── lib
│   └── project
│       └── libvector3.so
│       └── libvector3.a        products of installation / building
├── docs
│   └── Doxyfile
├── include
│   └── project
│       └── vector3.hpp
│_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
│
├── src
│   └── CMakeLists.txt
│   └── Doxyfile.in
│   └── project                 part of version-control / source-distribution
│       └── CMakeLists.txt
│       └── vector3.hpp
│       └── vector3.cpp
│       └── test
│           └── test_vector3.cpp
│_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
│
├── build
└── test                        working directories for building / testing
    └── test_vector3

这里有几点需要注意。首先,你的 src 目录的子目录应该镜像你的 include 目录的子目录,这只是为了保持直观(另外,尽量保持你的子目录结构合理平坦(浅),因为文件夹的深层嵌套通常比其他任何事情都更麻烦)。其次,“include”目录只是一个安装目录,它的内容就是从 src 目录中挑选出来的任何头文件。

第三,CMake 系统旨在分布在源子目录中,而不是作为顶层的一个 CMakeLists.txt 文件。这使事情保持本地化,这很好(本着将事情分成独立部分的精神)。如果您添加新源、新标头或新测试程序,您只需在相关子目录中编辑一个小而简单的 CMakeLists.txt 文件,而不会影响其他任何内容。这也使您可以轻松地重组目录(CMakeLists 是本地的并且包含在被移动的子目录中)。顶级 CMakeLists 应该包含大部分顶级配置,例如设置目标目录、自定义命令(或宏)以及查找系统上安装的包。较低级别的 CMakeLists 应该只包含简单的标头、源和单元测试源列表,以及将它们注册到编译目标的 cmake 命令。

Quote: CMakeLists.txt 应该如何查看才能仅构建库或库和测试?

基本答案是 CMake 允许您从“全部”中明确排除某些目标(这是在您键入“make”时构建的),您还可以创建特定的目标包。我不能在这里做一个 CMake 教程,但你自己找出来是相当直接的。然而,在这种特定情况下,推荐的解决方案当然是使用 CTest,它只是一组额外的命令,您可以在 CMakeLists 文件中使用这些命令来注册许多标记为单元的目标(程序)-测试。因此,CMake 会将所有测试放在一个特殊的构建类别中,而这正是您所要求的,所以问题解决了。

Quote: 此外,我还看到很多项目都有构建广告bin 目录。构建是否发生在构建目录中,然后二进制文件移出到 bin 目录中?测试和库的二进制文件会在同一个地方吗?或者将其结构如下更有意义:

在源代码之外有一个构建目录(“源外”构建)确实是唯一明智的做法,这是当今事实上的标准。所以,就像 CMake 人推荐的那样,就像我遇到的每个程序员一样,肯定地,在源目录之外有一个单独的“构建”目录。至于 bin 目录,嗯,这是一个约定,按照我在本文开头所说的那样,坚持它可能是一个好主意。

Quote: 我也想使用 doxygen 来记录我的代码。是否可以使用 cmake 和 make 自动运行它?

是的。这是不可能的,太棒了。根据您想要获得的花哨,有几种可能性。 CMake 确实有一个 Doxygen 模块(即find_package(Doxygen)),它允许您注册将在某些文件上运行 Doxygen 的目标。如果你想做更多花哨的事情,比如更新 Doxyfile 中的版本号,或者为源文件自动输入日期/作者标记等等,这一切都可以通过一点 CMake 功夫来实现。通常,这样做将涉及您保留一个源 Doxyfile(例如,我放在上面的文件夹布局中的“Doxyfile.in”),它具有要被 CMake 的解析命令找到和替换的令牌。在my top-level CMakeLists file,你会发现这样一个 CMake 功夫,它与 cmake-doxygen 一起做了一些花哨的事情。

【讨论】:

  • 所以main.cpp 应该转到trunk/bin
【解决方案3】:

构建项目

我一般会赞成以下几点:

├── CMakeLists.txt
|
├── docs/
│   └── Doxyfile
|
├── include/
│   └── project/
│       └── vector3.hpp
|
├── src/
    └── project/
        └── vector3.cpp
        └── test/
            └── test_vector3.cpp

这意味着您有一组非常明确定义的 API 文件用于您的库,并且该结构意味着您的库的客户端会这样做

#include "project/vector3.hpp"

而不是不太明确的

#include "vector3.hpp"


我喜欢 /src 树的结构与 /include 树的结构相匹配,但这确实是个人喜好。但是,如果您的项目扩展为包含 /include/project 中的子目录,则通常有助于匹配 /src 树中的子目录。

对于测试,我倾向于让它们“靠近”他们测试的文件,如果你最终在 /src 中找到了子目录,那么如果其他人想要找到给定文件的测试,这是一个非常容易遵循的范例代码。


测试

其次,我想使用 Google C++ 测试框架对我的代码进行单元测试,因为它看起来相当容易使用。

Gtest 确实使用简单,并且在功能方面相当全面。它可以很容易地与gmock 一起使用以扩展其功能,但我自己对 gmock 的体验不太好。我已经准备好接受这很可能是由于我自己的缺点造成的,但是 gmock 测试往往更难创建,而且更脆弱/难以维护。 gmock 棺材中的一个大钉子是它真的不适合智能指针。

这是对一个大问题(可能并不真正属于 S.O.)的一个非常琐碎和主观的答案

您是否建议将此与我的代码捆绑在一起,例如在“inc/gtest”或“contrib/gtest”文件夹中?如果捆绑,您建议使用 fuse_gtest_files.py 脚本来减少数量或文件,还是保持原样?如果没有捆绑,这个依赖如何处理?

我更喜欢使用 CMake 的 ExternalProject_Add 模块。这避免了您必须将 gtest 源代码保留在存储库中,或将其安装在任何地方。它会自动下载并构建在您的构建树中。

见我的answer dealing with the specifics here

在编写测试时,这些测试通常是如何组织的?我在想每个类都有一个 cpp 文件(例如 test_vector3.cpp),但都编译成一个二进制文件,这样它们就可以很容易地一起运行?

好计划。


建筑

我是 CMake 的粉丝,但与您的测试相关问题一样,S.O.可能不是就这样一个主观问题征求意见的最佳场所。

CMakeLists.txt 的外观如何才能仅构建库或库和测试?

add_library(ProjectLibrary <All library sources and headers>)
add_executable(ProjectTest <All test files>)
target_link_libraries(ProjectTest ProjectLibrary)

库将显示为目标“ProjectLibrary”,测试套件将显示为目标“ProjectTest”。通过将库指定为测试 exe 的依赖项,构建测试 exe 将自动导致库在过期时重新构建。

我还看到很多项目都有一个构建和一个 bin 目录。构建是否发生在构建目录中,然后二进制文件移出到 bin 目录中?测试的二进制文件和库会放在同一个地方吗?

CMake 推荐“源外”构建,即您在项目外部创建自己的构建目录并从那里运行 CMake。这样可以避免构建文件“污染”您的源代码树,如果您使用的是 vcs,这是非常可取的。

可以指定二进制文件在构建后被移动或复制到不同的目录,或者默认情况下它们在另一个目录中创建,但通常不需要。如果需要,CMake 提供了全面的方式来安装您的项目,或者使其他 CMake 项目可以轻松“找到”您项目的相关文件。

关于 CMake 自己的 support for finding and executing gtest tests,如果您将 gtest 作为项目的一部分构建,这在很大程度上是不合适的。 FindGtest 模块真正设计用于在您的项目之外单独构建 gtest 的情况。

CMake 提供自己的测试框架 (CTest),理想情况下,每个 gtest 案例都将添加为 CTest 案例。

但是,FindGtest 提供的 GTEST_ADD_TESTS 宏允许作为单独的 ctest 用例轻松添加 gtest 用例,因为它不适用于除 TESTTEST_F 之外的 gtest 宏。使用TEST_PTYPED_TEST_P 等的Value-Type-parameterised 测试根本不被处理。

据我所知,这个问题没有一个简单的解决方案。获取 gtest 用例列表的最可靠方法是使用标志 --gtest_list_tests 执行测试 exe。但是,这只能在构建 exe 后完成,因此 CMake 无法使用它。这让您有两种选择; CMake 必须尝试解析 C++ 代码以推断测试的名称(如果您想考虑所有 gtest 宏、注释掉的测试、禁用的测试,则极端不平凡),或者手动将测试用例添加到CMakeLists.txt 文件。

我还想使用 doxygen 来记录我的代码。是否可以使用 cmake 和 make 自动运行它?

是的 - 虽然我在这方面没有经验。 CMake 为此提供了FindDoxygen

【讨论】:

    【解决方案4】:

    除了其他(优秀的)答案之外,我将描述一个我一直用于相对大型项目的结构。
    我不打算解决关于 Doxygen 的子问题,因为我只想重复其他答案中所说的内容。


    基本原理

    为了模块化和可维护性,项目被组织为一组小单元。 为了清楚起见,我们将它们命名为 UnitX,其中 X = A、B、C、...(但它们可以有任何通用名称)。 然后组织目录结构以反映这种选择,必要时可以对单元进行分组。

    解决方案

    基本目录布局如下(单元内容稍后详述):

    project
    ├── CMakeLists.txt
    ├── UnitA
    ├── UnitB
    ├── GroupA
    │   └── CMakeLists.txt
    │   └── GroupB
    │       └── CMakeLists.txt
    │       └── UnitC
    │       └── UnitD
    │   └── UnitE
    

    project/CMakeLists.txt 可以包含以下内容:

    cmake_minimum_required(VERSION 3.0.2)
    project(project)
    enable_testing() # This will be necessary for testing (details below)
    
    add_subdirectory(UnitA)
    add_subdirectory(UnitB)
    add_subdirectory(GroupA)
    

    project/GroupA/CMakeLists.txt:

    add_subdirectory(GroupB)
    add_subdirectory(UnitE)
    

    project/GroupB/CMakeLists.txt:

    add_subdirectory(UnitC)
    add_subdirectory(UnitD)
    

    现在来看不同单元的结构(我们以 UnitD 为例)

    project/GroupA/GroupB/UnitD
    ├── README.md
    ├── CMakeLists.txt
    ├── lib
    │   └── CMakeLists.txt
    │   └── UnitD
    │       └── ClassA.h
    │       └── ClassA.cpp
    │       └── ClassB.h
    │       └── ClassB.cpp
    ├── test
    │   └── CMakeLists.txt
    │   └── ClassATest.cpp
    │   └── ClassBTest.cpp
    │   └── [main.cpp]
    

    到不同的组件:

    • 我喜欢将源代码 (.cpp) 和标题 (.h) 放在同一个文件夹中。这避免了重复的目录层次结构,使维护更容易。对于安装,只过滤头文件是没有问题的(尤其是 CMake)。
    • 目录UnitD 的作用是稍后允许包含#include &lt;UnitD/ClassA.h&gt; 的文件。此外,在安装本机时,您可以照原样复制目录结构。请注意,您还可以在子目录中组织源文件。
    • 我喜欢一个 README 文件来总结该单元的内容并指定有关它的有用信息。
    • CMakeLists.txt 可以简单地包含:

      add_subdirectory(lib)
      add_subdirectory(test)
      
    • lib/CMakeLists.txt:

      project(UnitD)
      
      set(headers
          UnitD/ClassA.h
          UnitD/ClassB.h
          )
      
      set(sources
          UnitD/ClassA.cpp
          UnitD/ClassB.cpp    
          )
      
      add_library(${TARGET_NAME} STATIC ${headers} ${sources})
      
      # INSTALL_INTERFACE: folder to which you will install a directory UnitD containing the headers
      target_include_directories(UnitD
                                 PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
                                 PUBLIC $<INSTALL_INTERFACE:include/SomeDir>
                                 )
      
      target_link_libraries(UnitD
                            PUBLIC UnitA
                            PRIVATE UnitC
                            )
      

      在这里,请注意,没有必要告诉 CMake 我们想要 UnitAUnitC 的包含目录,因为在配置这些单元时已经指定了这一点。此外,PUBLIC 会告诉所有依赖于UnitD 的目标,它们应该自动包含UnitA 依赖项,而UnitC 则不需要(PRIVATE)。

    • test/CMakeLists.txt(如果您想使用 GTest,请参阅下文):

      project(UnitDTests)
      
      add_executable(UnitDTests
                     ClassATest.cpp
                     ClassBTest.cpp
                     [main.cpp]
                     )
      
      target_link_libraries(UnitDTests
                            PUBLIC UnitD
      )
      
      add_test(
              NAME UnitDTests
              COMMAND UnitDTests
      )
      

    使用 GoogleTest

    对于 Google Test,最简单的方法是它的源代码是否存在于您的源代码目录中,但您不必自己实际添加它。 我一直在使用this project 自动下载它,我将它的用法包装在一个函数中以确保它只下载一次,即使我们有多个测试目标。

    这个CMake函数如下:

    function(import_gtest)
      include (DownloadProject)
      if (NOT TARGET gmock_main)
        include(DownloadProject)
        download_project(PROJ                googletest
                         GIT_REPOSITORY      https://github.com/google/googletest.git
                         GIT_TAG             release-1.8.0
                         UPDATE_DISCONNECTED 1
                         )
        set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) # Prevent GoogleTest from overriding our compiler/linker options when building with Visual Studio
        add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL)
      endif()
    endfunction()
    

    然后,当我想在我的一个测试目标中使用它时,我将以下行添加到CMakeLists.txt(这是上面的示例,test/CMakeLists.txt):

    import_gtest()
    target_link_libraries(UnitDTests gtest_main gmock_main)
    

    【讨论】:

    • 你用 Gtest 和 cmake 做了很好的“hack”!有用! :)
    猜你喜欢
    • 2021-06-11
    • 2013-05-23
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    • 2012-01-20
    • 2010-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多