# Linking library to library...

**URL:** <https://discourse.cmake.org/t/linking-library-to-library/10854>\
**Category:** Code\
**Created:** [May 14, 2024, 2:21pm UTC](https://discourse.cmake.org/t/linking-library-to-library/10854 "2024-05-14T14:21:35Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Oodini](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/o/db5fbb/32.png) [@Oodini](https://discourse.cmake.org/u/Oodini)\
**Post date:** [May 14, 2024, 2:21pm UTC](https://discourse.cmake.org/t/linking-library-to-library/10854/1 "2024-05-14T14:21:35Z")

</div>

Hello,

I am trying to do a hierarchy of static libraries :

Executable → libC → libB → libA

Each target retrieves the used library with `FetchContent`.  
The problem is that `target_link_directories()` and `target_link_libraries()` are not recursive.  
So, for libC, for exemple, I have to fetch _libB_ and libA. The final client has to know all the dependency hierarchy.

I know it isn’t possible to link a static library to an other static library at the system level, but could CMake, when calling `target_link_libraries(libA libB)`, extract the object files in libA, and put them in libB ?

---

<div class="post-metadata">

**Author:** ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)\
**Post date:** [May 14, 2024, 2:52pm UTC](https://discourse.cmake.org/t/linking-library-to-library/10854/2 "2024-05-14T14:52:48Z")

</div>

CMake propagate automatically static libraries to the final target. So;

```cmake
target_link_libraries(libB libA)
target_link_libraries(libC libB)
add_library(final_lib SHARED libC)

```

Any final target, like executable or shared library, linking with `libC` will also link against `libB` **and** `libA`. Just ensure that [CMP0099](https://cmake.org/cmake/help/latest/policy/CMP0099.html) policy is set to `NEW`.

And, by the way, if you are using CMake targets, you don’t have to specify any directory. Using `target_link_libraries()` command is enough.

---

<div class="post-metadata">

**Author:** ![Oodini](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/o/db5fbb/32.png) [@Oodini](https://discourse.cmake.org/u/Oodini)\
**Post date:** [May 14, 2024, 3:00pm UTC](https://discourse.cmake.org/t/linking-library-to-library/10854/3 "2024-05-14T15:00:16Z")

</div>

> [@marc.chevrier](#):
>
> CMake propagate automatically static libraries to the final target.

Well, the problem is the 3 lines of code are made in _different CMake_ projects.

- project A: builds libA, and puts the libA installation files on a server
- project B: fetches libA’s content from the server, link it to libB, and puts the libB installation files on a server
- project C: **fetches libA’s content from the server (I’d like avoiding that),** fetches libB’s content from the server, link them to libC, and puts the libC installation files on a server
- project final: **fetches libA’s content from the server (I’d like avoiding that),** **fetches libB’s content from the server (I’d like avoiding that),** fetches libC’s content from the server, link them to final\_lib, and puts the final\_lib installation files on a server

---

<div class="post-metadata">

**Author:** ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)\
**Post date:** [May 14, 2024, 3:28pm UTC](https://discourse.cmake.org/t/linking-library-to-library/10854/4 "2024-05-14T15:28:11Z")

</div>

In this case you have to use [OBJECT](https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#object-libraries) libraries to aggregate all objects in various static libraries.

---

<div class="post-metadata">

**Author:** ![Oodini](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/o/db5fbb/32.png) [@Oodini](https://discourse.cmake.org/u/Oodini)\
**Post date:** [May 14, 2024, 3:47pm UTC](https://discourse.cmake.org/t/linking-library-to-library/10854/5 "2024-05-14T15:47:23Z")

</div>

Very interesting.

But if I take the examples given in the documentation :

```auto
add_library(archive OBJECT archive.cpp zip.cpp lzma.cpp)
add_library(archiveExtras STATIC $<TARGET_OBJECTS:archive> extras.cpp)
add_executable(test_exe $<TARGET_OBJECTS:archive> test.cpp)

```

Does that work if for the first instruction, I set **STATIC** instead of **OBJECT**?  
Because the coder of archive cannot know if the client of archive will want to use it to be aggregated to an other library, or to be linked it to an executable.

Also, I am troubled by this sentence :

> The link (or archiving) step of those other targets will use the object files from `OBJECT` libraries that are _directly_ linked.

Why emphasing this “directly”, whereas it is said later there will be a transitive propagation ?

---

<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:** [March 4, 2025, 9:17am UTC](https://discourse.cmake.org/t/linking-library-to-library/10854/6 "2025-03-04T09:17:38Z")

</div>

> [@Oodini](#):
>
> Why emphasing this “directly”, whereas it is said later there will be a transitive propagation ?

If `OBJECT` library objects were transitive, then if you have (assuming `PUBLIC` scoping for links):

- `Executable -> libC`
- `libC -> libD`
- `libD -> objectLib`

`libD`, `libC`, \*and` `Executable`would *each* get the objects of`objectLib` placed. This is generally not allowed.

As for this feature:

> [@Oodini](#):
>
> when calling `target_link_libraries(libA libB)`, extract the object files in libA, and put them in libB ?

See this issue: [https://gitlab.kitware.com/cmake/cmake/-/issues/22679](https://gitlab.kitware.com/cmake/cmake/-/issues/22679)
