I'm looking for a way to share CMake scripts between multiple projects.
In a repo called somelib
I have a cmake
folder, and from the other projects I want to include the scripts in it. In the CMakeLists.txt
of somelib
I include many files from the cmake
folder.
My projects declare "somelib" as an external dependency like so :
include(FetchContent)
FetchContent_Declare(
somelib
GIT_REPOSITORY git@git.somewhere.com:somewhere/somelib.git
GIT_TAG origin/master
)
FetchContent_MakeAvailable(somelib)
I'm not sure this is a good practice so feel free to correct me, but I'm willing to include the CMakeLists.txt
of somelib
so that my project include all the files that somelib
includes.
So after the FetchContent_MakeAvailable
I did :
include(${somelib_SOURCE_DIR}/CMakeLists.txt)
This include by itself works just fine, but the issue lies in the CMakeLists.txt
of somelib
. Indeed, the includes it does are not relative to its location resulting in errors like :
CMake Error at _build/_deps/somelib-src/CMakeLists.txt:26 (include):
include could not find load file:
cmake/Cache.cmake
Call Stack (most recent call first):
CMakeLists.txt:47 (include)
CMake Error at _build/_deps/somelib-src/CMakeLists.txt:29 (include):
include could not find load file:
cmake/Linker.cmake
Call Stack (most recent call first):
CMakeLists.txt:47 (include)
CMake Error at _build/_deps/somelib-src/CMakeLists.txt:33 (include):
include could not find load file:
cmake/CompilerWarnings.cmake
Call Stack (most recent call first):
CMakeLists.txt:47 (include)
I do realize that instead of including the CMakeLists.txt
I could simply do :
include(${somelib_SOURCE_DIR}/cmake/Cache.cmake)
include(${somelib_SOURCE_DIR}/cmake/Linker.cmake)
include(${somelib_SOURCE_DIR}/cmake/CompilerWarnings.cmake)
But this will become quite big as the time goes by (plus it will be duplicated between all my projects), so I would like to have a single entry point, a single thing I can include to have everything at hand in my CMakeLists. Is it possible ?
Don't do include(${somelib_SOURCE_DIR}/CMakeLists.txt)
since FetchContent_MakeAvailable(somelib)
already calls add_subdirectory
on that same file.
If you want access to its scripts, then just run:
list(APPEND CMAKE_MODULE_PATH "${somelib_SOURCE_DIR}/cmake")
include(Cache)
include(Linker)
include(CompilerWarnings)
But this will become quite big as the time goes by (plus it will be duplicated between all my projects), so I would like to have a single entry point, a single thing I can include to have everything at hand in my CMakeLists. Is it possible?
You could also move these helpers to their own repository and have every project FetchContent that. Then its CMakeLists.txt would just have this:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE)
And you would run:
FetchContent_MakeAvailable(my_helpers)
include(MyHelpers)
where MyHelpers.cmake
simply include()
s all the other helpers.