本文介绍了CMake FetchContent多次下载外部依赖项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始使用FetchContent来自动下载外部依赖项.与旧的方法相比,它的效果很好,但是我有一个可能与FetchContent本身无关的问题-外部依赖项被下载了多次.我实际上是在为Android平台构建,但这没什么大不了的.我这样称呼CMake就是 cmake -B build/arm64-v8a ... cmake -B build/x86 ... .我需要为每个ABI(arm64-v8a,x86等)使用单独的构建文件夹,以避免重建,因为我经常在ABI之间切换.但是,当我使用简单的FetchContent构造,例如:

I started to use FetchContent for automatical download of external dependencies. It works nicely compared to older approaches but I have one problem which is probably not related to FetchContent itself - external dependencies are downloaded multiple times. I'm actually building for Android platform but that doesn't matter much.I call CMake like this cmake -B build/arm64-v8a ... or cmake -B build/x86 .... I need separate build folders for each ABI (arm64-v8a, x86, ...) to avoid rebuilds because I switch between ABIs frequently.But when I use simple FetchContent constructions like:

FetchContent_Declare(
  googletest
  GIT_REPOSITORY https://github.com/google/googletest.git
  GIT_TAG        release-1.8.0
)

FetchContent_GetProperties(googletest)
if(NOT googletest_POPULATED)
  FetchContent_Populate(googletest)
  add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
endif()

它将每个ABI下载一次外部项目(换句话说-使用不同构建文件夹的每个CMake调用一次),因为 googletest_POPULATED 在使用不同构建文件夹的下一个CMake调用中不可见.如果将源下载一次,那就太好了.

it will download external project once per ABI (in other words - once per CMake call using different build folder), because googletest_POPULATED is not visible in next CMake call using different build folder. It would be awesome if sources would be downloaded once.

所以我尝试在 FetchContent_Declare 中传递 SOURCE_DIR 以将源代码保存一级(在 build/_deps/googletest-src 中而不是build/< abi>/_ deps/googletest-src 文件夹).它正确保存了源,但由于似乎 googletest-subbuild 文件夹(位于 build/< abi>/_ deps 下)管理着 googletest_POPULATED,仍触发了重新下载标志.

So I tried passing SOURCE_DIR in FetchContent_Declare to save source one level up (in build/_deps/googletest-src not build/<abi>/_deps/googletest-src folder). It saved sources correctly but re-download was still triggered as it seems that googletest-subbuild folder (located under build/<abi>/_deps) manages googletest_POPULATED flag.

我该如何解决?

推荐答案

尝试使用 FETCHCONTENT_BASE_DIR 共享创建的处理下载管理的CMake项目.然后,请确保使用单独的构建目录来构建软件.

Try using FETCHCONTENT_BASE_DIR to share the CMake project that is created that handles downloading management. Then make sure to use separate build directories for building the software.

cmake_minimum_required(VERSION 3.13)
project(fc_twice)

include (FetchContent)
set(FETCHCONTENT_QUIET off)
get_filename_component(fc_base "../fc_base"
                       REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
set(FETCHCONTENT_BASE_DIR ${fc_base})

FetchContent_Declare(
  googletest
  GIT_REPOSITORY https://github.com/google/googletest.git
  GIT_TAG        release-1.8.0
)

FetchContent_GetProperties(googletest)
if(NOT googletest_POPULATED)
  FetchContent_Populate(googletest)
  #create gt build directory in binary tree
  add_subdirectory(${googletest_SOURCE_DIR} gt)
endif()

在构建目录之间切换时,会重复一些簿记项目,但实际下载只会发生一次.您应该看到以下消息:

When switching between build directories some bookkeeping items are repeated but the actual download will only occur once. You should see the message:

  Performing download step (git clone) for 'googletest-populate'
  -- Avoiding repeated git clone, stamp file is up to date: 'C:/Users/XXX/Desktop/temp/so_fc/fc_base/googletest-subbuild/googletest-populate-prefix/src/googletest-populate-stamp/googletest-populate-gitclone-lastrun.txt'

我使用命令 cmake -S src/-B bld1 cmake -S src/-B bld2 进行了测试,然后切换回去并进行构建.

I tested using the commands cmake -S src/ -B bld1 and cmake -S src/ -B bld2 and switched back and for building them.

这篇关于CMake FetchContent多次下载外部依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 15:46