# cmake target\_link\_libraries INTERFACE works incorrect

**URL:** https://discourse.cmake.org/t/cmake-target-link-libraries-interface-works-incorrect/7207
**Category:** Usage
**Created:** [January 6, 2023, 7:05am UTC](https://discourse.cmake.org/t/cmake-target-link-libraries-interface-works-incorrect/7207 "2023-01-06T07:05:16Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![Sergey\_Vlasov](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sergey_vlasov/32/3061_2.png) [@Sergey\_Vlasov](https://discourse.cmake.org/u/Sergey_Vlasov)
#### Post date: [January 6, 2023, 7:05am UTC](https://discourse.cmake.org/t/cmake-target-link-libraries-interface-works-incorrect/7207/1 "2023-01-06T07:05:16Z")

</div>

CMAKE 3.25.1, linux, GCC 4.6.4

I have the following CMakeLists.txt:

```auto
cmake_minimum_required(VERSION 3.12)
project(all)

add_library(lib1 STATIC lib1.cpp lib1.h)
add_library(lib1_wrapper INTERFACE)
target_link_libraries(lib1_wrapper INTERFACE lib1 ${CMAKE_DL_LIBS})

add_library(lib3 STATIC lib3.cpp lib3.h)
add_library(lib3_wrapper INTERFACE)
target_link_libraries(lib3_wrapper INTERFACE lib3 ${CMAKE_DL_LIBS})

add_executable(app app.cpp)
target_link_libraries(app PRIVATE lib1_wrapper lib3_wrapper)

```

I expect to see the following linker command in the link.txt:

```auto
/usr/bin/g++ CMakeFiles/app.dir/app.cpp.o -o app liblib1.a -ldl liblib3.a -ldl

```

But the last -ldl is missing and I see this:

```auto
/usr/bin/g++ CMakeFiles/app.dir/app.cpp.o -o app liblib1.a -ldl liblib3.a

```

It will be compilation error if lib1 doesn’t really use libdl functions and lib3 does.

The question: is this a bug or I’m doing something wrong?

The problem is that lib1 doesn’t really use libdl. Only lib3 uses it. And I get the following error:

```auto
/usr/bin/ld: liblib3.a(lib3.cpp.o): in function `test_lib3()':
lib3.cpp:(.text+0xa): undefined reference to `dlclose'
collect2: ld returned 1 exit status

```

Once again, why we don’t have -ldl after lib3.a in the linker arguments?

---

<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 6, 2023, 6:03pm UTC](https://discourse.cmake.org/t/cmake-target-link-libraries-interface-works-incorrect/7207/2 "2023-01-06T18:03:46Z")

</div>

Flags tend to be deduplicated, so this isn’t surprising. However, if `lib3` itself needs `-ldl`, why only add it via the `_wrapper` target? Does it work if you add it directly to the target(s) that need it?

---

<div class="post-metadata">

### Author: ![Sergey\_Vlasov](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sergey_vlasov/32/3061_2.png) [@Sergey\_Vlasov](https://discourse.cmake.org/u/Sergey_Vlasov)
#### Post date: [January 6, 2023, 6:58pm UTC](https://discourse.cmake.org/t/cmake-target-link-libraries-interface-works-incorrect/7207/3 "2023-01-06T18:58:39Z")

</div>

Good question. It really works but … This is only demo. In the real project I have access only to wrappers. And each \*\_wrapper refers to several IMPORTED libs beside it. Some libs in \_wrapper need -ldl and I don’t know how to add -ldl correctly to the end of the **final list** of libraries. Even if I add -ldl here:

```auto
add_executable(app app.cpp)
target_link_libraries(app PRIVATE lib1_wrapper lib3_wrapper -ldl)

```

it is useless… because the final list will be:

```auto
/usr/bin/g++ CMakeFiles/app.dir/app.cpp.o -o app -ldl liblib1.a liblib3.a

```

> Flags tend to be deduplicated  
> Probably so. But correct deduplication should be:

```auto
/usr/bin/g++ CMakeFiles/app.dir/app.cpp.o -o app liblib1.a liblib3.a -ldl

```

Optimization is important but the order of libs is more important IMHO

---

<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 7, 2023, 3:24am UTC](https://discourse.cmake.org/t/cmake-target-link-libraries-interface-works-incorrect/7207/5 "2023-01-07T03:24:13Z")

</div>

> [@Sergey\_Vlasov](#):
>
> Optimization is important but the order of libs is more important IMHO

CMake does offer some control over static library _cycles_, but fine-grained control over the link line is not something CMake provides because IDEs make their own command lines from a list of properties CMake sets up in the IDE project files.

---

<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: [January 7, 2023, 3:51am UTC](https://discourse.cmake.org/t/cmake-target-link-libraries-interface-works-incorrect/7207/6 "2023-01-07T03:51:25Z")

</div>

> [@Sergey\_Vlasov](#):
>
> I expect to see the following linker command in the link.txt:
> 
> ```auto
> /usr/bin/g++ CMakeFiles/app.dir/app.cpp.o -o app liblib1.a -ldl liblib3.a -ldl
> 
> ```

This expectation is incorrect. In your example, you specify this:

```auto
target_link_libraries(lib3_wrapper INTERFACE lib3 ${CMAKE_DL_LIBS})

```

This says only that something that links to `lib3_wrapper` needs to also link to `lib3` and `${CMAKE_DL_LIBS}`. Importantly, it does _not_ say that `lib3_wrapper` itself uses or requires either of those two libraries. If you want it to say that it does use/require them, that should be `PUBLIC` rather than `INTERFACE`.

---

<div class="post-metadata">

### Author: ![Sergey\_Vlasov](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sergey_vlasov/32/3061_2.png) [@Sergey\_Vlasov](https://discourse.cmake.org/u/Sergey_Vlasov)
#### Post date: [January 7, 2023, 6:33am UTC](https://discourse.cmake.org/t/cmake-target-link-libraries-interface-works-incorrect/7207/7 "2023-01-07T06:33:33Z")

</div>

Scott, I can’t do

```auto
target_link_libraries(lib3_wrapper PUBLIC lib3 ${CMAKE_DL_LIBS})

```

cmake gives error on that: INTERFACE library can only be used with the INTERFACE keyword of target\_link\_libraries

so, there is no was to provide the correct libs order in this case?

---

<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: [January 7, 2023, 6:42am UTC](https://discourse.cmake.org/t/cmake-target-link-libraries-interface-works-incorrect/7207/8 "2023-01-07T06:42:41Z")

</div>

Ah, sorry, I misread. But your expectation is still incorrect. The constraints you have specified are the following:

- `lib1` depends on nothing. Anything that links to `lib1` doesn’t get any usage requirements at all. This implies `lib1` does not depend on anything outside itself.
- Similarly, `lib3` depends on nothing. Anything that links to `lib3` also doesn’t get any usage requirements at all. This implies `lib3` does not depend on anything outside itself. Note in particular this means you are saying that `lib3` does not depend on the `dl` library.
- `lib1_wrapper` adds `lib1` and `${CMAKE_DL_LIBS}` as usage requirements for anything that links to `lib1_wrapper`, but note that this doesn’t imply any ordering of those two libraries.
- Similarly `lib3_wrapper` adds `lib3` and `${CMAKE_DL_LIBS}` as usage requirements for anything that links to `lib3_wrapper`, but again this doesn’t imply any ordering of those two libraries.

So when CMake constructs the dependency graph for app, it adds `lib1` and `dl` as dependencies of `lib1_wrapper`, then when it adds the dependencies for `lib3_wrapper`, it can see that `dl` has already been added and doesn’t need to be added a second time.

I suspect the actual constraints you have are that `lib1` and `lib3` should both link directly to `${CMAKE_DL_LIBS}`. If `lib1` and `lib3` depend on the `dl` library, you _must_ specify that constraint on `lib1` and `lib3`, not on the wrappers.

---

<div class="post-metadata">

### Author: ![Sergey\_Vlasov](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sergey_vlasov/32/3061_2.png) [@Sergey\_Vlasov](https://discourse.cmake.org/u/Sergey_Vlasov)
#### Post date: [January 7, 2023, 7:02am UTC](https://discourse.cmake.org/t/cmake-target-link-libraries-interface-works-incorrect/7207/9 "2023-01-07T07:02:05Z")

</div>

Craig, thanks for detailed explanation.

But in the real life lib1 and lib3 are imported libs. I can do:

```auto
target_link_libraries(lib1 INTERFACE ${CMAKE_DL_LIBS})

```

but…

lib1 will be unwrapped to something like /some/absolute/path/lib1.a and again there is a chance that it will be

-ldl /some/absolute/path/lib1.a

but not

/some/absolute/path/lib1.a -ldl

---

<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 7, 2023, 2:46pm UTC](https://discourse.cmake.org/t/cmake-target-link-libraries-interface-works-incorrect/7207/10 "2023-01-07T14:46:27Z")

</div>

> [@Sergey\_Vlasov](#):
>
> But in the real life lib1 and lib3 are imported libs. I can do:

It’s important to include these details in examples when asking questions (especially when something doesn’t match your expectations; those details could be very important, as it is here). We cannot know what you’ve simplified out based on any assumptions you’ve had on how things work. There are a few things to try:

- fix the project that exports the imported libraries (if made by another project)
- if made by a `FindX.cmake`, add `${CMAKE_DL_LIBS}` to the target’s `INTERFACE_LINK_LIBRARIES` property.

---

<div class="post-metadata">

### Author: ![Sergey\_Vlasov](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sergey_vlasov/32/3061_2.png) [@Sergey\_Vlasov](https://discourse.cmake.org/u/Sergey_Vlasov)
#### Post date: [January 8, 2023, 9:40am UTC](https://discourse.cmake.org/t/cmake-target-link-libraries-interface-works-incorrect/7207/11 "2023-01-08T09:40:05Z")

</div>

Thanks Ben, Craig

It’s really something wrong with my project. In the test project I can add -ldl to `INTERFACE\_LINK\_LIBRARIES of the imported libraries and everything is ok.

Thanks for feedback!
