# Wrapper of target\_link\_libraries

**URL:** https://discourse.cmake.org/t/wrapper-of-target-link-libraries/6956
**Category:** Code
**Tags:** os:linux
**Created:** [November 25, 2022, 2:47pm UTC](https://discourse.cmake.org/t/wrapper-of-target-link-libraries/6956 "2022-11-25T14:47:01Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![NoName](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/n/58f4c7/32.png) [@NoName](https://discourse.cmake.org/u/NoName)
#### Post date: [November 25, 2022, 2:47pm UTC](https://discourse.cmake.org/t/wrapper-of-target-link-libraries/6956/1 "2022-11-25T14:47:01Z")

</div>

Hi,  
I’m working on a large project that has managed its external library dependencies in a single “libraries.cmake” file so far. For each external dependency there is a find\_package call. Now I want to change it to a more modular design where every library knows it’s own dependency to get rid of the master declaration.

For this I wrote a wrapper for target\_link\_libraries and introduced symbols like “EXTERNAL\_LIB\_{NAME}” where “{NAME}” is the Libray internal name (e.g. PNG).

A sample target\_link\_libraries\_wrapper call looks like:  
`target_link_libraries_wrapper(my_libA EXTERNAL_LIB_PNG)`

The wrapper evaluates the “EXTERNAL\_LIB\_” and calls for the given {NAME} a macro “USE\_EXTERNAL\_LIB\_{NAME}”. In this example USE\_EXTERNAL\_LIB\_PNG. These macros then do the work of find\_package, include\_directories and target\_link\_libraries call.

This works well for most of my libraries. But there are some where the transitive include\_directories do not work.

A library my\_libB which is linked to my\_libA do not get the my\_libA include\_directories (e.g. for library PNG) and therefore I get compilation errors. This was not the case with the master declaration. Even if i change the master declaration to use the new USE\_EXTERNAL\_LIB\_PNG macro instead of the direct find\_package it works.

Now to my questions:

- Is this a good practice to have a more modular design?
- Is it ok to have such a “late” binding?
- How can I do it better?
- Why do I get these compilation errors to unknown includes?

Bests,  
Michael

---

<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: [November 30, 2022, 7:40pm UTC](https://discourse.cmake.org/t/wrapper-of-target-link-libraries/6956/2 "2022-11-30T19:40:07Z")

</div>

I think instead of working with multiple `target_*` commands, you should use `find_package()` and use `IMPORTED` targets. That will save you a lot of calls and variable shuffling.

I suspect that your main issue is that everything is using `PRIVATE` visibility. Instead, each usage should have an associated visibility:

```cmake
target_link_libraries_wrapper(my_libA
  PUBLIC EXTERNAL_LIB_PNG)

```

Another thing you can do is make your own targets that “encapsulate” each external dependency:

```cmake
find_package(PNG REQUIRED)
add_library(external_png INTERFACE)
target_link_libraries(external_png INTERFACE PNG::PNG)

# …
target_link_libraries(my_libA PUBLIC external_png)

```

which wouldn’t require any wrapper.

---

<div class="post-metadata">

### Author: ![NoName](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/n/58f4c7/32.png) [@NoName](https://discourse.cmake.org/u/NoName)
#### Post date: [December 2, 2022, 12:30pm UTC](https://discourse.cmake.org/t/wrapper-of-target-link-libraries/6956/3 "2022-12-02T12:30:22Z")

</div>

Interesting approach to have a dedicated encapsulated external dependency.

Sadly this would not solve the problem to run the find\_package for a external library only when there is a target which links to it. In our project it’s possible to have derivatives which do not need to have find\_package calls to libraries they don’t use, but others do.

For this reason a late dependency tracking would be nice.

Bests and a nice weekend  
Michael

---

<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: [December 2, 2022, 1:16pm UTC](https://discourse.cmake.org/t/wrapper-of-target-link-libraries/6956/4 "2022-12-02T13:16:08Z")

</div>

`IMPORTED` targets are scoped, but your own `add_library` is not, so the `add_library` version can be accessed from anywhere once made without another `find_package` call.

---

<div class="post-metadata">

### Author: ![NoName](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/n/58f4c7/32.png) [@NoName](https://discourse.cmake.org/u/NoName)
#### Post date: [December 2, 2022, 1:36pm UTC](https://discourse.cmake.org/t/wrapper-of-target-link-libraries/6956/5 "2022-12-02T13:36:25Z")

</div>

Ok yes, but I need a find\_package call even if the library is not linked from any target. Or am I misunderstand you.

---

<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: [December 2, 2022, 1:40pm UTC](https://discourse.cmake.org/t/wrapper-of-target-link-libraries/6956/6 "2022-12-02T13:40:30Z")

</div>

You can do `find_package` when the target is needed and ignore it all if it ends up being unnecessary.

---

<div class="post-metadata">

### Author: ![NoName](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/n/58f4c7/32.png) [@NoName](https://discourse.cmake.org/u/NoName)
#### Post date: [December 8, 2022, 11:58am UTC](https://discourse.cmake.org/t/wrapper-of-target-link-libraries/6956/7 "2022-12-08T11:58:06Z")

</div>

Hi Ben,

I solved the problem with a combined approach. I use your proposal about to have an interface library with my symbolic name scheme. Now I do have a late binding with all advantages of a interface libraries. If a symbolic name is never used, there is never a find\_package call and no interface library is built.

Have many thanks for your help.

Bests,  
Michael
