Allow to manually set dependencies for some targets


I would like to know if CMake provide a way of fixing dependencies for a particular targets.

The use-case is to build once, analyze result’s real dependencies with a custom script(linker map or dwarf+nm, gcc -M), and setting them in this “CMake dependencies cache”. For example, if lib A is composed of A.o B.o A.h B.h, an executable using only symbols/headers from A.o would not depend on B.o/B.h when it links on lib A.

If it’s not possible actually, would it be possible to modify CMake to create a disk cache for each dependencies. If this cache exist for a target, then CMake would pass any step where it populate the dependencies graph for this target, just relying on the cache information.

I tried to look at CMake code source, but it’s a bit complex, there seem to be different graphes? It’s hard for me to localize all the places in the code that would need to be bypassed if cache exist for this target (is just in AddTargetDepend okay?)

If you thinks it’s doable, with a bit of guidance regarding where to be careful, I would work on this.

If you think it’s doom to fail, what could I do then?

AFAIK, there is no such thing as a “CMake dependencies cache”.

CMake provides a higher level abstraction on top of build tools, so you could start by making a proof of concept using make or Ninja, then we can see how to make it work in CMake terms.

I would rather have some advice on how to reach this modifying CMake sources if it’s doable. After really quickly checking the sources, it looks like putting a cache logic in AddTargetDepend seem to be a good start and require almost no change. But before trying stuff like that I would like some advice’s by people that have really good knowledge on CMake.

The idea is to allow external tools to setup minimal dependencies at next reconfiguration of project. This would not impact project that dont populate the cache while allowing people to fight in an external dedicated process to reach the automatic minimal dependencies feature .

Without considering the existence of a poc to achieve auto minimal dependencies with linker map or dwarf+nm, I think it’s a good idea to allow the dev to manually fix the dependencies of his library unit tests to the one file it really test, instead of the whole library it links to.

Tup is the only build system that try to address the minimal dependencies now, with a ld preload hack on the compiler. I think this is an overlooked feature. My build take care to test only the tests that failed or changed. Similarly, it collect some performances data only when dependencies are outdated. When libraries are involved, I end up running all my test/perf suit all the time for no reason.

I think this is a behavior that belongs at the tool level, not the CMake level. I have no idea how one would make this work for Visual Studio or Xcode as they do their own internal dependency tracking. The changes to the make and ninja files would likely be substantial as well. You could use a CMAKE_CXX_COMPILER_LAUNCHER to rewrite the dependency file as you’d like from your own cache, but I thnk that would again only really work in the make and ninja generators.

Yes, I also think that it should be a feature offered by the tool level, without any reconfiguration step of CMake.
I thought the problem with other tools was that the dependencies were just not modifiable. But it’s even worst if they are hardcoded. My plan would not work with the latter I guess.

I dont understand how CMAKE_CXX_COMPILER_LAUNCHER could help (probably because I dont know what you mean by the dependency file). I will take a deeper look next week. But the reason why I was really pleased with using AddTargetDepend for stuff I would find in my cache was because I thought CMake dependencies abstraction would magically deals with the dependencies for any supported tool.

You are telling me that there is no function in CMake that could help me abstract the recreation of dependencies list for a target for every tool that support the feature?

Thanks for the answer

Ninja supports dynamic dependencies. You can read more about this here:

Ninja’s dyndep is a different feature. I suppose one could use it here, but seeing as it only works there (and would need some overhaul for Makefiles, would be possible there too), it’s not something we’d be able to offer generically since I don’t think VS or Xcode supports that. Then again, they’ll need the feature to support C++20 modules, so who knows.