【问题标题】:How do i use add_subdirectory() after ExternalProject_Add() has finished downloading?ExternalProject_Add() 下载完成后如何使用 add_subdirectory()?
【发布时间】:2020-07-27 18:47:44
【问题描述】:

我问的问题基本上和here 一样。然而这个问题没有得到回答。

我想在我的项目中使用 googletest。为此,我使用 ExternalProject_Add(),它使用 git 克隆测试套件。之后,我喜欢使用add_subdirectory()

这也是official repository 中描述的内容。这种方法的好处是,googletest 中的构建脚本自己处理构建过程。

但问题是,add_subdirectory() 找不到源文件夹,因为它从一开始就不存在。所以add_subdirectory()应该依赖于ExternalProject_Add()的补全。

是否可以使 add_subdirectory() 依赖于 ExternalProject_Add(),就像 add_dependencies() 对目标所做的那样?

附言。如果我将 add_subdirectory() 注释掉,构建它(由于缺少 googletest 库而以错误结束),取消注释并再次构建它(成功),我可以让它全部编译。

ExternalProject_Add(
    googletest
    GIT_REPOSITORY  https://github.com/google/googletest.git
    GIT_TAG         master
    CONFIGURE_COMMAND ""
    BUILD_COMMAND     ""
    INSTALL_COMMAND   ""
    TEST_COMMAND      ""
    )

ExternalProject_Get_Property(googletest source_dir binary_dir)
set(GTEST_INCLUDE_DIR ${source_dir}/googletest/include)
set(GMOCK_INCLUDE_DIR ${source_dir}/googlemock/include)


add_subdirectory(${source_dir}
                 ${binary_dir})

【问题讨论】:

  • 使用ExternalProject_Add() 添加的项目仅在构建时下载,IIRC。
  • Here is 完整的带有依赖关系的工作示例。
  • 在我尝试之前,我不愿意将其作为答案,但 FetchContent 似乎是您真正想要的 CMake 命令。这是 3.11 中的新功能。
  • @John,我认为这正是值得接受的答案。
  • @dani 和 @Bikineev,我扩展了我的原始答案以包含更多讨论和FetchContent

标签: cmake googletest external-project


【解决方案1】:

我使用this tutorial 来实现这一点。只需将您的ExternalProject 代码放在一个单独的文件中,例如“CMakeLists.txt.dependencies”,然后使用execute_process 启动另一个cmake。我首先使用configure_file 将配置信息注入到外部项目中,并将其复制到构建树中。

configure_file(CMakeLists.txt.dependency.in dependency/CMakeLists.txt)
execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
        WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/dependency" )
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
        WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/dependency" )

请注意,本教程在单独的 CMakeLists.txt 文件中包含 ExternalProject 代码。 gtest 官方文档也是如此。那是因为ExternalProject 在构建时运行,而不是在配置时运行。这是一个在配置时使用ExternalProject 的技巧,方法是将其放入第三个项目并在主 CMake 配置步骤的中间执行单独的 CMake+build 运行。

在 3.11 版 CMake 中添加了 FetchContent 命令。我没有使用它,但是文档使它看起来像是ExternalProject 的配置时替代品。这将在配置时获取内容,使其可用于以后的add_subdirectory 命令。

ExternalProjectFetchContent 命令适用于少量小的和/或模糊的依赖项。如果您的依赖项超过 2 个、大型和/或流行,我建议您查看像 Conan 这样的依赖项管理器。它与 CMake 的合作非常好。

【讨论】:

    【解决方案2】:

    您没有正确遵循该方法。 CMakeLists.txt.in 文件中的最终命令应该只有 ExternalProject_Add()

    CMakeLists.txt.in 文件由外部CMakeLists.txt 文件调用,以便子项目处理在配置时通过execute_process() 进行。 CMakeLists.txt.in 只是一个美化的下载者。

    因此,所有其他命令(如 add_subdirectory())都添加到外部 CMakeLists.txt 文件中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多