I am trying to use a small subproject in a cmake master project using the FetchContent
method. Specifically, in the CMakeLists.txt
of my master project, I have the lines
include(FetchContent)
FetchContent_Declare(subproject GIT_REPOSITORY https://url/to/my_subproject)
FetchContent_MakeAvailable(subproject)
When I enter cmake
in the master project, the subproject is cloned, but the configuration fails.
Specifically, the ${CMAKE_SOURCE_DIR}
variable in the subproject contains the source directory of the master project, rather than that of the subproject, so directories relative to it are incorrect. The ${PROJECT_SOURCE_DIR}
variable correctly points to the subproject root, and the ${CMAKE_CURRENT_SOURCE_DIR}
variable correctly points to the current directory in the subproject.
My questions are:
${CMAKE_SOURCE_DIR}
variable be replaced with ${PROJECT_SOURCE_DIR}
)?cmake -P
?)Unlike to ExternalProject_Add
function, which configures a subproject as a separate CMake project, the FetchContent_MakeAvailable
effectively calls
add_subdirectory(<subproject_source_dir> <binary_dir>)
So, when a subproject is configured, it accesses master variables. Exception is a variable which is set by the subproject itself, or a variable which is automatically set by CMake according to the scope (like CMAKE_CURRENT_SOURCE_DIR
).
While ability for a project to be used via FetchContent is useful, not all CMake projects are developed to support such usage. That is, you may fill an issue for a project which uses CMAKE_SOURCE_DIR
variable in its calculations. But please mark that issue as a "feature request", not a "bug". (Unless the project's documentation explicitly describes the usage via FetchContent).
Is there a workaround for the master project?
Since the variable CMAKE_SOURCE_DIR
cannot be set manually, the master project has no other choice than including modified subproject.
When call FetchContent_Declare
, you could specify some executable as PATCH_COMMAND
option (the option is described in ExternalProject). That way you may run not only patch
, but e.g. a sed
script which replaces CMAKE_SOURCE_DIR
with some other "scoped" variable.