Enumerate all transitive dependencies of target?


Like some other developers, I need to copy external dependency DLLs to executable’s directory.

I’ve checked this topic. Unfortunately, suggested solution doesn’t fit that well

First of all, it lists all dependency DLLs, both project, thirdparty and system ones. Thus it requires additional filtering. Second, it takes considerable time due to multiple calls to dumpbin. Third, it doesn’t work as expected if libraries were already copied to runtime output directory.

My investigation shows that it’s virtually impossible to list whole dependency subtree. LINK_LIBRARIES property is properly populated (albeit with direct deps) only when generator expressions are expanded. Even if you get that list during file(GENERATE …), you won’t be able to enumerate even second level - because CMake context is not accessible at that point.
My best bet is to list all transitive deps subtree manually and use file(GENERATE) to manually copy all files.

Is there some proper way to list whole dependency subtree and work with it at generation time, like we work with normal variables?

IMO CMake requires more systematic way to tap into generation time. Generator expressions are “black box” in this regard. You can neither expand them at will nor properly process expansion results when they’re available.


Yes, specifying what is in which bucket would make the signature far more complicated.

I would do all of the scanning up front and then finally copy files over (or remember which files were already copied and filter them out too).

As for the way generator expressions work, they do so because the expand after any custom logic is possible. Being able to post-process them and further influence the build would cause CMake to have to run that loop until some fix point is reached (not guaranteed and easy to make infinite loops).

This approach is very fragile as it may easily break if applied mid-development.

We could at least have some way to manually expand them, provided necessary expansion context. AFAIU most info like toolchain, generator etc. are available globally from start, and expansion mostly requires configuration and target. ATM certain data, like target’s direct dependencies list, are not available to script. This isn’t an issue in your script but becomes one for imported target graphs. As of possible recursion, freezing properties should solve it.