我有两个cmake项目。其中一个使用googletest,其中第二个也使用它。还有,我在第二个项目中使用了第一个项目。
我在github上有第二个项目,googletest也在github上。因此,当我使用
构建我的第一个项目时,我想下载它们ExternalProject_Add
命令。
这是简化的文件夹结构:
.itemImage img {
max-width: 100%;
}
ProjectA
| build/
| include/
| src/
| modules/
| | ProjectB/
| | | CMakeLists.txt
| | googletest/
| | | CMakeLists.txt
| CMakeLists.txt
的简化结构:
ProjectB
现在我有一个重要的问题:可以下载googletest代码一次吗?现在我下载两次,一次ProjectB/
| build/
| include/
| src/
| modules/
| | googletest/
| | | CMakeLists.txt
| CMakeLists.txt
,第二次ProjectA
。
我可以添加简化的ProjectB
代码,但我不认为这里需要它。
答案 0 :(得分:1)
如果您不想两次下载Google C ++测试框架,只需使用正确的cmake查找模块,让它从您的环境中找到您需要的内容。
请参阅FindGTest
。
上面链接的示例用法:
enable_testing()
find_package(GTest REQUIRED)
add_executable(foo foo.cc)
target_link_libraries(foo GTest::GTest GTest::Main)
add_test(AllTestsInFoo foo)
话虽如此,他们是不同的项目,有自己的模块。最好明确一下。
您仍然可以在ProjectB
中添加一个自定义cmake查找模块,该模块在gtest
内查找ProjectA
。无论如何,它是一个脆弱的解决方案,因为它会在ProjectA
中的依赖关系发生变化时立即中断。
评论中的问题:
gtest看起来真的很好,但我想知道我的项目是否比gtest(例如ProjectC)不同,那我该怎么办?我正在寻找更通用的解决方案。
如果我无法通过正确的查找模块(以及需要时的版本)查找系统中的依赖项,我通常更愿意明确它们。因此,我将所需的依赖项添加到每个项目中,即使它意味着重新编译它们两次
一个可以回答为什么的问题:如果ProjectA
取决于给定模块的标记 x ,ProjectB
需要标记 y < / em>上班?如果这两个标签打破了彼此的API(不幸的是有时它会发生),除非你明确了解每个项目的依赖关系,否则你将遇到麻烦。
答案 1 :(得分:1)
您可以将googletest视为第三个外部项目,然后将其位置作为CMake缓存变量传递到两个项目中。这样可以确保您只需下载一次googletest,但这可能比直接构建googletest作为项目的一部分要方便。您可以创建第四个顶级项目,将三个项目(googletest,projectA和projectB)中的每个项目组合在一起,这样您就可以确保在需要配置projectA或projectB之前构建googletest。 googletest的ExternalProject会将gtest和gmock目标安装到其安装区域。然后,您将该目录传递给projectA和projectB的ExternalProjects作为google测试的位置。您可以使用projectA和projectB中的FindGTest模块,让您的顶级项目为projectA和projectB设置GTEST_ROOT
缓存变量。这可能是最简单的选择。
另一个选择是下载并构建googletest作为projectA的一部分(请参阅here了解我建议执行此操作的方法),然后让projectB重新使用googletest源代码,或者更好的是,从projectA构建目标。您可以将projectA带入projectB,就像上面的链接将googletest带入projectA一样。我们在工作中使用这样的安排来汇集许多不同的项目,每个项目可以单独构建或作为其他项目的一部分构建。这种方法的一个优点是,如果您使用的是像Visual Studio,Xcode或Qt Creator这样的IDE,您可以看到源列表中所有项目的来源以及IDE的问题检测,重构工具等往往会有更完整的整体构建视图。它还倾向于最小化必须在项目之间手动传递的信息,因为CMake在一个构建中看到整个源和目标集,因此不需要显式处理特定于平台的库名,不同的构建输出目录结构等等。
如果你想将projectA保留为projectB的ExternalProject,那么你仍然可以重新使用来自projectA的googletest源代码,但是你必须非常小心地设置目标间依赖关系,以确保在需要之前构建projectA googletest来源。您可能还最终必须手动确定将内容下载到projectA并在projectA中构建的内容,如果您的项目是在多个平台上构建的,那么这可能会很麻烦。听起来这是最接近你问的怎么做,但我可能建议尝试上述两种方法中的一种。
还有其他选择,例如使用像hunter这样的包管理器,但这可能与问题的原始焦点相差太远。