This provides a CMake function, simililar to find_package
, that will
also fetch the packages from git (using FetchContent
) that are not found.
You probably don't want to use this. Probably, you'd be better of with Conan, vcpkg, or other package managers. This builds the packages, offers no caching across projects and is generally just to improve prototyping speed.
Ready to use, complete projects including various libraries can be found here:
Imagine you want to get the great fmt.
If you have cunta setup you would just write (in your CMakeLists.txt
):
include(cmake/cunta.cmake)
find_or_fetch_package(fmt)
And that's it! You will use fmt from your system, if it is available and if not you will build it from sources.
It will also look into extern
directory whether the package is there as a git submodule.
But where does it take the package from?
- It checks the submodules in
extern/
to try and find package there (add it as add_subdirectory if that is the case) - If it's not found in submodules it looks for tha package with find_package.
- If it's not found in submodules and not in the system, then it fetches the git repository (with fetch_content) into and does add_subdirectory on it.
CMake 3.11 and above and git for packages that require submodules. Also, you need to be able to build those packages themselves.
If you are interested (but I doubt it), feel free to send Pull Requests with more packages/fixes/ideas/anything.
The setup is just downloading somehow the cunta.cmake
file and making sure it is included from your CMakeLists.txt
(for example if cunta.cmake is in cmake directory you would add include(cmake/cunta.cmake
)
You have a project:
.
├── main.cpp
└─── CMakeLists.txt
You first get the cunta.cmake file somehow.
wget https://raw.githubusercontent.com/shrumo/cunta/master/cunta.cmake
And put it inside cmake folder. (or whatever, just be able to reach it
with CMakeLists.txt
) You can also use FetchContent
to fetch the
cunta.cmake
file. Or even just clone it as a git submodule.
So you have it somewhere:
.
├── main.cpp
├─── CMakeLists.txt
└── cmake
└── cunta.cmake
Then in your CMakeLists.txt
you do:
include(cmake/cunta.cmake)
If the project shares a dependency with other imported package there might be a conflict. Example:
find_or_fetch_package(raylib)
find_or_fetch_package(glfw)
Leads to:
CMake Error at build/_deps/raylib-src/src/external/glfw/src/CMakeLists.txt:96 (add_library):
add_library cannot create target "glfw" because an imported target with the
same name already exists.
This can be solved in various ways. One of them is use the target provided by the other target.
Some other ugly hack might be to redefine add_subdirectory
. (but we shouldn't redefine CMake commands)
If anyone cares I will solve it.
We use VERBOSE CMake messages to provide more information on where the things are actually fetched from. To see the VERBOSE lines use:
cmake .. --log-level=VERBOSE
It might also be useful to print all the properties of a target to verify the include paths and other properties are correct.