使用依赖项测试构建项目:CMake FetchContent验证目标

qij5mzcb  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(124)

我在构建具有两个定义相同目标的外部依赖项的项目时遇到问题。
我的目标是能够编译项目的测试沿着项目的依赖测试。为此,我考虑在使用FetchContent从源代码编译时构建单元测试。如果包含include(CTest),则任何后续对add_test的调用都将包含该测试,因此之后所有测试(project + dependencies ')可以在构建目录(ctest --test-dir build)上使用ctest运行:

$ ctest --test-dir build
Internal ctest changing into directory: /home/eulersson/cmake-fetchcontent-conflicting-targets/build
Test project /home/eulersson/cmake-fetchcontent-conflicting-targets/build
(FIRST IT RUNS THE TESTS FROM THIS PROJECT (TEST_FOO))
      Start  1: test-foo
 1/62 Test  #1: test-foo ..........................   Passed    0.02 sec
 (NOW IT WOULD RUN THE TESTS FROM CJSON (DEPENDENCY))
      Start  2: cJSON_test
 2/62 Test  #2: cJSON_test ........................   Passed    0.02 sec
      Start  3: parse_examples
[...]
 (NOW IT WOULD RUN THE TESTS FROM LIBZMQ (DEPENDENCY))
[...]

字符串
这有意义吗?也许有另一种符合最佳实践的方法?
当向CMake项目中添加各种依赖项时,如果你还想沿着构建单元测试,我会遇到这样的问题:目标(在本例中是单元测试库“unity”)被你想构建测试的各种依赖项添加了两次(add_library(unity STATIC [...])):

  • add_library(unity [...])在libzmq:https://github.com/zeromq/libzmq/blob/959a133520dfc80d29e83aa7ef762e1d0327f63b/tests/CMakeLists.txt#L206-L209
  • cJSON中的add_library(unity [...]):https://github.com/DaveGamble/cJSON/blob/19ff92da79ee37c81a4cdf1f50a8dd1cbb02e84f/tests/CMakeLists.txt#L2

可重现的示例:https://github.com/eulersson/cmake-fetchcontent-conflicting-targets:在定义相同的非命名空间目标的项目上使用FetchContent时出现问题。

$ git clone https://github.com/eulersson/cmake-fetchcontent-conflicting-targets
$ cd cmake-conflicting-targets
$ cmake -S . -B build
[...]
CMake Error at build/_deps/cjson-src/tests/CMakeLists.txt:2 (add_library):
  add_library cannot create target "unity" because another target with the
  same name already exists.  The existing target is a static library created
  in source directory
  "/Users/ramon/Devel/conflicting-targets/build/_deps/libzmq-src/tests".  See
  documentation for policy CMP0002 for more details.


如果这些目标具有名称空间,这就不是问题。
什么是一个好的工作区?
先谢了。

q7solyqu

q7solyqu1#

在你的情况下,你不能使用FetchContent。当你有多个依赖项想要定义相同的目标名称时,它们会发生冲突,正如你所观察到的。在这种情况下,你不能直接将依赖项带入主项目,但你可以使用ExternalProject构建它们,因为它会创建自己的单独子构建。
在您的场景中,您可能应该使用基于ExternalProject的超级构建。从严格意义上说,这意味着您的主项目本质上只不过是一堆ExternalProject_Add()调用。您必须设置每个调用之间的依赖关系,以正确表达哪些调用依赖于哪些其他调用。如果它们都是基于CMake的依赖关系,您可以设置每个CMAKE_PREFIX_PATH指向其他ExternalProject_Add()调用安装到的位置。有些人选择使用单个,所有这些都有一个公共的安装区域,以保持简单。其他人选择将每个安装到自己的单独安装区域。您可以找到一个合理的讨论,Kitware的CMake Superbuilds and Git Submodules博客文章中提到了超级构建模式,尽管它缺乏示例。
最终,你可能想要的是我在CMake问题跟踪器中提出的project-level namespaces功能。据我所知,还没有人在研究它,我不希望自己在中期内有时间致力于它。这将是一个相当大的任务。

相关问题