# How $\<LINK\_ONLY:...\> really works?

**URL:** <https://discourse.cmake.org/t/how-link-only-really-works/10673>\
**Category:** Code\
**Created:** [April 16, 2024, 10:59am UTC](https://discourse.cmake.org/t/how-link-only-really-works/10673 "2024-04-16T10:59:33Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![silverqx](https://discourse.cmake.org/user_avatar/discourse.cmake.org/silverqx/32/2353_2.png) [@silverqx](https://discourse.cmake.org/u/silverqx)\
**Post date:** [April 16, 2024, 10:59am UTC](https://discourse.cmake.org/t/how-link-only-really-works/10673/1 "2024-04-16T10:59:33Z")

</div>

I need to understand this `$<LINK_ONLY:...>` genex in `INTERFACE_LINK_LIBRARIES` in the package config file.

I don’t understand what is written in the documentation.

> Content of …, except while collecting Transitive Usage Requirements, in which case it is the empty string.

Imagine a project with `CoreLib` and `SomeExe` that depends on this `CoreLib` and the `CoreLib` depends on `MySQL::MySQL` (MySQL client library).

`CoreLib` contains:

```cmake
target_link_libraries(CoreLib PRIVATE/PUBLIC/INTERFACE MySQL::MySQL)

```

I have observed if I do the `static` build (`BUILD_SHARED_LIB=OFF`) and `target_link_libraries()` is `PRIVATE` then:

```cmake
INTERFACE_LINK_LIBRARIES \$<LINK_ONLY:MySQL::MySQL>

```

If I do the `shared` build (`BUILD_SHARED_LIB=ON`) and `target_link_libraries()` is `PRIVATE` then `INTERFACE_LINK_LIBRARIES` of course doesn’t contain the `MySQL::MySQL` dependency (this is clear).

In all other cases (`PUBLIC`/`INTERFACE` and `shared`/`static` builds) it behaves normally (standard behavior; this is also clear):

```cmake
INTERFACE_LINK_LIBRARIES MySQL::MySQL

```

So this special behavior is only applied for `static` builds when the dependency is `PRIVATE`.

What it means? Is this dependency **propagated** in this case? (`static` `PRIVATE`) I don’t get it.

Thx for advice.

---

<div class="post-metadata">

**Author:** ![robert.maynard](https://discourse.cmake.org/user_avatar/discourse.cmake.org/robert.maynard/32/4_2.png) [@robert.maynard](https://discourse.cmake.org/u/robert.maynard)\
**Post date:** [April 16, 2024, 1:48pm UTC](https://discourse.cmake.org/t/how-link-only-really-works/10673/2 "2024-04-16T13:48:09Z")

</div>

Static libraries don’t really have a link phase. Very cruedly they are just an archive of object files that will be propagated to a real link line ( creation of a shared library or executable ).

So in your case you have stated a static library requires mysql, since you are static library that means the consumer of your static library needs to link against mysql ( since you don’t have a link line ).

Now since you have said PRIVATE linking that means you didn’t want compiler includes, defines, options, etc that are part of the `MySQL::MySQL` target to be propagated. To make this requirement true while propagating the MySQL::MySQL target as a dependency we wrap it in `$<LINK_ONLY>`. Therefore consumers of your static library satisify the requirements of static libraries and dependencies, but aren’t impacted by other transitive properties as requested by `PRIVATE`.

---

<div class="post-metadata">

**Author:** ![silverqx](https://discourse.cmake.org/user_avatar/discourse.cmake.org/silverqx/32/2353_2.png) [@silverqx](https://discourse.cmake.org/u/silverqx)\
**Post date:** [April 16, 2024, 1:55pm UTC](https://discourse.cmake.org/t/how-link-only-really-works/10673/3 "2024-04-16T13:55:06Z")

</div>

So that means that the MySQL::MySQL dependency will be propagated down to the `SomeExe` during exe linking? Of course without includes, defines, options, etc. but only for static builds and only if the `target_link_libraries()` was `PRIVATE`.

I understand what you are writing but it’s complex.

---

<div class="post-metadata">

**Author:** ![robert.maynard](https://discourse.cmake.org/user_avatar/discourse.cmake.org/robert.maynard/32/4_2.png) [@robert.maynard](https://discourse.cmake.org/u/robert.maynard)\
**Post date:** [April 16, 2024, 8:23pm UTC](https://discourse.cmake.org/t/how-link-only-really-works/10673/4 "2024-04-16T20:23:48Z")

</div>

That is correct.

So the end goal is to always create a correct build or executable. The implementation details of static libraries require CMake to punch through the `PRIVATE` keyword and pass specific things to ensure we don’t end up with link errors.
