如果文件夹存在,是否有一种简单的方法跳过 download_step,在 cmake ExternalProject_Add 中

Is there an easy way of skip download_step if folder exists, in cmake ExternalProject_Add

我需要 CMakeLists.txt 中的 ExternalProject_Add 来跳过 download_step 进行 git 下载,如果已经有一个文件夹克隆了 repo,比如 update_step 如果您提供 GIT_TAG,但不想编写自定义 DOWNLOAD_COMMAND。如果手动将依赖项添加到文件夹项目,基本上只需要项目完全脱机构建。

例如:

ExternalProject_Add(civ
  SOURCE_DIR            ${PROJECT_SOURCE_DIR}/test
  BUILD_COMMAND         ${MAKE_EXE}
  BINARY_DIR            "./bin"
  INSTALL_COMMAND       ""
  GIT_REPOSITORY        "https://github.com/test/test"
  GIT_TAG               "v1.0"
  LOG_DOWNLOAD          on
  CMAKE_ARGS
    "-DTuberosumTools_DIR=${TUBEROSUMTOOLS_DIR}"
)

这个,删除 test 文件夹并在每次第一次构建项目时再次克隆它(如果我手动删除构建文件夹),我可以完全离线构建,但确实需要使用它总是离线。已经尝试设置缓存变量,如:

set(FRESH_DOWNLOAD off CACHE BOOL "download a fresh copy of all dependencies")

include(ExternalProject)
ExternalProject_Add(civ
  SOURCE_DIR            ${PROJECT_SOURCE_DIR}/test
  BUILD_COMMAND         ${MAKE_EXE}
  BINARY_DIR            "./bin"
  INSTALL_COMMAND       ""
  GIT_REPOSITORY        "https://github.com/test/test"
  GIT_TAG               "v1.0"
  if(NOT FRESH_DOWNLOAD)
    DOWNLOAD_COMMAND      ""
  endif()
  CMAKE_ARGS
    "-DTuberosumTools_DIR=${TUBEROSUMTOOLS_DIR}"
)

除非另有说明,否则完全禁用下载,但 if 内部对 ExternalProject_Add() 的调用显然不起作用,并且在外部使用 if 会引入额外的代码,更难实现mantain,而且很丑。

任何简单的替代方案都是有效的,在此先感谢。

Update/Patch Step Options: Whenever CMake is re-run, by default the external project’s sources will be updated if the download method supports updates (e.g. a git repository would be checked if the GIT_TAG does not refer to a specific commit).

UPDATE_DISCONNECTED <bool> When enabled, this option causes the update step to be skipped. It does not, however, prevent the download step. The update step can still be added as a step target (see ExternalProject_Add_StepTargets()) and called manually. This is useful if you want to allow developers to build the project when disconnected from the network (the network may still be needed for the download step though).

参考:https://cmake.org/cmake/help/latest/module/ExternalProject.html

当调用函数或宏时,CMake 允许替换一个变量,该变量一次包含多个参数。也就是说,您可以有条件地定义一个负责下载步骤的变量:

set(FRESH_DOWNLOAD off CACHE BOOL "download a fresh copy of all dependencies")

include(ExternalProject)
if (NOT FRESH_DOWNLOAD)
    # Define the variable to disable DOWNLOAD step
    set(civ_DOWNLOAD DOWNLOAD_COMMAND      "")
else()
    # Define an empty variable.
    # This actually can be omitted since absent variable is treated as empty.
    set(civ_DOWNLOAD)
endif()

ExternalProject_Add(civ
  SOURCE_DIR            ${PROJECT_SOURCE_DIR}/test
  BUILD_COMMAND         ${MAKE_EXE}
  BINARY_DIR            "./bin"
  INSTALL_COMMAND       ""
  GIT_REPOSITORY        "https://github.com/test/test"
  GIT_TAG               "v1.0"
  ${civ_DOWNLOAD} # IMPORTANT: Do not use double quotes here.
  CMAKE_ARGS
    "-DTuberosumTools_DIR=${TUBEROSUMTOOLS_DIR}"
)

您可以尝试 FetchContent,然后 ExternalProject 使用 FetchContent 下载的目录。类似的东西:

include(FetchContent)
FetchContent_Declare(
    mylib
    GIT_REPOSITORY "git@github.com:username/mylib.git"
    GIT_TAG <some sha>
)
FetchContent_MakeAvailable(mylib)

include(ExternalProject)
ExternalProject_Add(
    mylib
    SOURCE_DIR "_deps/mylib-src/"
    CONFIGURE_COMMAND ""
    INSTALL_COMMAND ""
    BUILD_COMMAND "pwd"
)