Is there already some generic way of dealing with fetchContent from CMake? So far, I was usually able to patch the projects and provide the required dependencies by hand but things have started to become transitive now where dependencies themselves start to have their own series of dependencies managed using fetchContent. This is starting to become a real hassle that probably needs to be solved in a somewhat generic way.
CMake seems to support setting a dependency provider on the high-level (Using Dependencies Guide — CMake 3.28.3 Documentation) which might be the way forward here. Though, given the lack of a global lockfile in CMake (like, e.g. Rust has) this still requires one run to capture all the dependencies.
Is anyone already working on solving this in a somewhat generic way?
I wrote some Nix code that extracts FetchContent declarations from a CMakeLists.txt file, defines derivations for them, and sets the CMake variables for FetchContent to use the nix-provided copy. The FetchContent declarations have the repo url, git hash, and name, so I just also add a comment with the hash. For an example of the CMake variables, passing -DFETCHCONTENT_SOURCE_DIR_HELLO=/nix/store/...-hello/ would override FetchContent declarations for hello (case-insensitive, the last part of the variable is uppercased).
This does not solve the dependencies of dependencies problem (though I’m of the opinion that dependencies shouldn’t be in the business of locking deps for consumers…).
With IFD, it might be possible to write a derivation that extracts all the definitions, and produces the info for generating CMake flags for all the dependencies, including transitive ones.
The generic solution to this issue is to convince upstream to use FetchContent_Declare with FIND_PACKAGE_ARGS, so that FetchContent_MakeAvailable short-circuits if we provide it a ready dependency from Nixpkgs (vcpkg, debian, etc). This also requires a reasonably up-to-date cmake version
I created an approach that can deal with this and not require individual patching per project. Not sure if this is clean enough for Nixpkgs, but I will use it for personal projects. Works very well for CMake and might actually cover quite some additional use-cases.
I was using your answer (for a nur pkg) and after wondering for while, why cmake was still trying to fetch content i realised a mistake in your answer:
it shoule be -DFETCHCONTENT_SOURCE_DIR_HELLO=/nix/store/...-hello (UPPERCASE) instead of the lower-case hello.
i found that in the cmake docs
and your parsing code also calls toUpper here
could you edit that, for future people using your answer? (or we just hope future ppl read on for a few answers…)
Could you explain this further, please? Currently trying to package something that uses FetchContent and I want to make an upstream issue that asks them to use your suggestion.