# Enumerate all transitive dependencies of target?

**URL:** https://discourse.cmake.org/t/enumerate-all-transitive-dependencies-of-target/2523
**Category:** Usage
**Created:** [January 12, 2021, 6:23pm UTC](https://discourse.cmake.org/t/enumerate-all-transitive-dependencies-of-target/2523 "2021-01-12T18:23:30Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![target.san](https://discourse.cmake.org/user_avatar/discourse.cmake.org/target.san/32/1093_2.png) [@target.san](https://discourse.cmake.org/u/target.san)
#### Post date: [January 12, 2021, 6:23pm UTC](https://discourse.cmake.org/t/enumerate-all-transitive-dependencies-of-target/2523/1 "2021-01-12T18:23:30Z")

</div>

Hello!

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

I’ve checked [this topic](https://discourse.cmake.org/t/copying-dependent-dlls-to-executable-directory/852). 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.

Thanks

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [January 12, 2021, 7:06pm UTC](https://discourse.cmake.org/t/enumerate-all-transitive-dependencies-of-target/2523/2 "2021-01-12T19:06:45Z")

</div>

> [@target.san](#):
>
> Thus it requires additional filtering.

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

> [@target.san](#):
>
> Third, it doesn’t work as expected if libraries were already copied to runtime output directory.

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).

---

<div class="post-metadata">

### Author: ![target.san](https://discourse.cmake.org/user_avatar/discourse.cmake.org/target.san/32/1093_2.png) [@target.san](https://discourse.cmake.org/u/target.san)
#### Post date: [January 13, 2021, 6:41am UTC](https://discourse.cmake.org/t/enumerate-all-transitive-dependencies-of-target/2523/3 "2021-01-13T06:41:24Z")

</div>

> [@ben.boeckel](#):
>
> 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).

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

> [@ben.boeckel](#):
>
> 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).

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.
