问题
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()
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.
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.
How can I fix this?
回答1:
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'
I tested using the commands cmake -S src/ -B bld1
and cmake -S src/ -B bld2
and switched back and for building them.
来源:https://stackoverflow.com/questions/56329088/cmake-fetchcontent-downloads-external-dependencies-multiple-times