# add\_subdirectory() and target\_link\_libraries() ordering

**URL:** https://discourse.cmake.org/t/add-subdirectory-and-target-link-libraries-ordering/15539
**Category:** Code
**Created:** [March 4, 2026, 6:25pm UTC](https://discourse.cmake.org/t/add-subdirectory-and-target-link-libraries-ordering/15539 "2026-03-04T18:25:19Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Diltsman](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/d/71c47a/32.png) [@Diltsman](https://discourse.cmake.org/u/Diltsman)
#### Post date: [March 4, 2026, 6:25pm UTC](https://discourse.cmake.org/t/add-subdirectory-and-target-link-libraries-ordering/15539/1 "2026-03-04T18:25:19Z")

</div>

When writing a CMakeLists.txt file, I have always called target\_link\_libraries() with a list of targets that I am generating in other directories, then I call add\_subdirectory() to add the files that create the targets. AI is telling me that I need to call add\_subdirectory() before target\_link\_libraries() so that the target is defined before the call to target\_link\_libraries() references it. I have never had an issue with target names resolving. What is the correct way to handle this?

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [March 4, 2026, 8:58pm UTC](https://discourse.cmake.org/t/add-subdirectory-and-target-link-libraries-ordering/15539/2 "2026-03-04T20:58:54Z")

</div>

`AI` does not know all, and sometime it `hallucinate`!

There are more ways to do it:

One is:

```cmake
add_executable(your_target ...)

add_library(foo)
# ...
add_library(bar)

add_subdirectory(path/to/foo) # to use target_source(foo ...)
# ...
add_subdirectory(path/to/bar) # to use target_source(bar ...)

target_link_libraries(your_target PUBLIC foo bar ...)

```

---

<div class="post-metadata">

### Author: ![Diltsman](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/d/71c47a/32.png) [@Diltsman](https://discourse.cmake.org/u/Diltsman)
#### Post date: [March 4, 2026, 9:06pm UTC](https://discourse.cmake.org/t/add-subdirectory-and-target-link-libraries-ordering/15539/3 "2026-03-04T21:06:37Z")

</div>

I agree. It does hallucinate often. I just want to know if this is a hallucination, or it is something that I didn’t know but should have known.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [March 4, 2026, 9:22pm UTC](https://discourse.cmake.org/t/add-subdirectory-and-target-link-libraries-ordering/15539/4 "2026-03-04T21:22:10Z")

</div>

Things are changing over the time. i.e.

`CMake 3.12 and earlier` prohibited `target_link_libraries()` from operating on a target defined in a different directory. If a subdirectory needed to make the target link to something, it couldn’t do so from within that subdirectory. …

from [Professional CMake](https://crascit.com/professional-cmake/)

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [March 5, 2026, 9:17pm UTC](https://discourse.cmake.org/t/add-subdirectory-and-target-link-libraries-ordering/15539/5 "2026-03-05T21:17:45Z")

</div>

Focusing on the original question, consider the following call:

```cmake
target_link_libraries(Algo PRIVATE SpecialSauce)

```

CMake will immediately issue an error if `Algo` isn’t a defined target. It is perfectly happy for `SpecialSauce` to not be defined yet, the only criteria is that it must eventually be defined somewhere before the end of the entire CMake configure execution. For example, the following is safe and supported:

```cmake
add_executable(App ...)

target_link_libraries(App PRIVATE Algo) # Algo doesn't exist yet, but App does

add_library(Algo STATIC ...)

```

I generally recommend that projects define things before they are referenced, but that isn’t a requirement for `target_link_libraries()` except for its first argument, as explained above. The reason I recommend that is occasionally projects try to do things that assume all referenced entities exist. I’m being deliberately vague about that, but I’ve seen it done a few times and sometimes by very commonly used projects. Now, projects shouldn’t generally do things like that, but occasionally they need to do something for which there’s no other workaround and the project is willing to accept the limitations of such logic.

---

<div class="post-metadata">

### Author: ![Lieven](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/l/c37758/32.png) [@Lieven](https://discourse.cmake.org/u/Lieven)
#### Post date: [March 10, 2026, 9:24am UTC](https://discourse.cmake.org/t/add-subdirectory-and-target-link-libraries-ordering/15539/6 "2026-03-10T09:24:18Z")

</div>

I think in large codebases (tens to hundreds of libraries, with tens of applications being build up by using some of those libraries), having this order always in place might be hard, many libraries in different folders. Say libraries A, B, C, D, and let’s assume they can be anywhere in the source tree, relative to one another, but when starting at the top level, the end result of several add\_subdirectory does however ensure, they would have been added in the order , A, B,C, D. Great, we met the requirement. And suddenly the implementation of B changes, in that way it uses ‘D’. Now what , restructure the source tree, move things around to make it work ? While feasible maybe not so much wanted.

Do note, that (if I recall correctly) with aliases this freedom is not there, and Foo::foo has to be known by the time somebody uses it as a dependency in target\_link\_libraries !

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [March 10, 2026, 9:05pm UTC](https://discourse.cmake.org/t/add-subdirectory-and-target-link-libraries-ordering/15539/7 "2026-03-10T21:05:12Z")

</div>

> [@Lieven](#):
>
> Do note, that (if I recall correctly) with aliases this freedom is not there, and Foo::foo has to be known by the time somebody uses it as a dependency in target\_link\_libraries !

Can you give a more fleshed out example of that? I’m not aware of any restriction specific to ALIAS targets like what you describe, but maybe I’m misunderstanding what you’re saying.

---

<div class="post-metadata">

### Author: ![Lieven](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/l/c37758/32.png) [@Lieven](https://discourse.cmake.org/u/Lieven)
#### Post date: [March 13, 2026, 5:40pm UTC](https://discourse.cmake.org/t/add-subdirectory-and-target-link-libraries-ordering/15539/8 "2026-03-13T17:40:24Z")

</div>

It seems this works now, I do remember years ago it did not work, since I ran into this problem, but as said those were tests and conclusions somewhere in the 2019-2020 time frame. Never re-tried it, so very happy to be stand corrected and know this is no longer a problem 🙂
