Error using FetchContent with URL

Hello,

I’m trying to download a binary dependency and put it in the same location as my source build (this is due to some legacy nonsense involving environment variables).

I do the following:

FetchContent_Declare(MyDependency
    URL my/dependency/resource.tar.gz
    HTTP_HEADER "PRIVATE-TOKEN: <private-token>" -L
    SOURCE_DIR ${CMAKE_BINARY_DIR}
)

FetchContent_MakeAvailable(MyDependency)

When I configure, I get the following after downloading the resource:

-- extracting... done
shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
chdir: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
cmake -E touch: failed to update "/path/to/project/build/_deps/myproject_subbuild/myproject-populate-prefix/src/myproject-populate-stamp/myproject-populate-download".

This is followed by some CMake errors about failing to direct populate, the most recent call being:

/path/to/cmake/Modules/FetchContent.cmake:1819:EVAL:2 (__FetchContent_directPopulate)

Removing the SOURCE_DIR line lets me download and configure in the expected way (except that my artifacts are now located in .../build/_deps/myproject-src/ which is a problem for the legacy nonsense involving environment variables).

Am I missing something else I need in the FetchContent invocation, or is this just not possible without a script or custom command or something?

Thanks in advance

Do not use ${CMAKE_BINARY_DIR} as the SOURCE_DIR. The ${CMAKE_BINARY_DIRECTORY} is already something CMake populates with various things, and trying to make it your dependency’s source directory will cause corruption. You can specify a subdirectory below ${CMAKE_BINARY_DIRECTORY} though (and I do this in some projects). For example:

FetchContent_Declare(MyDependency
    URL my/dependency/resource.tar.gz
    HTTP_HEADER "PRIVATE-TOKEN: <private-token>" -L
    SOURCE_DIR ${CMAKE_BINARY_DIR}/MyDependency
)

I’m also wondering about the -L at the end of the HTTP_HEADER line. That looks suspicious, it isn’t a HTTP header and looks more like a raw curl command line option, but CMake uses internal function calls directly in the C/C++ layer for its networking.

Hi Craig, thanks for the response.

My issue is mostly that pre-existing legacy systems require that these artifacts be located in the same directory, not a subdirectory or a parallel one. The old systems use python scripts to fetch dependencies, and I’m trying to unify everything in CMake. This only has to be done after the build is complete (at application runtime). Would you recommend a custom command to do this after the build is complete? I suppose I could create symlinks to the directory as well.

Regarding the -L, my code above works but definitely does not work without the -L. :person_shrugging:

Do you need the sources or the built binaries to all be located in the same directory? Those are two very different scenarios.

Regarding the -L , my code above works but definitely does not work without the -L .

I assume you’re using that to convince the implementation to follow redirections. I’d have to crawl through the implementation to find out if there’s an officially supported way to achieve that. I’m kinda surprised this works though, I would have expected it to cause an error (it should cause an error, since -L is not a valid HTTP header). Take this as a warning that using -L might stop working at any time with a future update to CMake.

Take this as a warning that using -L might stop working at any time with a future update to CMake.

Understood.

Do you need the sources or the built binaries to all be located in the same directory? Those are two very different scenarios.

We need the binaries of the dependencies (prebuilt, stored in a generic gitlab package repository) to be located in the same directory as our project’s built binaries.