# Automatically wrapping a static library in "whole-archive"/"no-whole-archive" when used during linking

**URL:** https://discourse.cmake.org/t/automatically-wrapping-a-static-library-in-whole-archive-no-whole-archive-when-used-during-linking/5883
**Category:** Code
**Created:** [June 17, 2022, 7:58am UTC](https://discourse.cmake.org/t/automatically-wrapping-a-static-library-in-whole-archive-no-whole-archive-when-used-during-linking/5883 "2022-06-17T07:58:16Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![ingolf](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/i/977dab/32.png) [@ingolf](https://discourse.cmake.org/u/ingolf)
#### Post date: [June 17, 2022, 7:58am UTC](https://discourse.cmake.org/t/automatically-wrapping-a-static-library-in-whole-archive-no-whole-archive-when-used-during-linking/5883/1 "2022-06-17T07:58:16Z")

</div>

Hi,

what is the correct way to add some linking flags whenever a certain static library is used when linking an executable?

Example:

- there is a static library `L` (providing its own public include directories and maybe depending on other libraries)
- whenever `L` is linked into an exectuable, the reference to `L` shall be enclosed in an `-Wl,--whole-archive` / `-Wl,--no-whole-archive` pair

During my search for a solution, I found [this message in the forum](https://discourse.cmake.org/t/encapsulating-link-arguments/1171/2), but got errors for instance because the static `jni_component` does not contain any sources.

I tried to modify the example a litte, and apparently the following _seems_ to work somehow…

```auto
# this is the *actual* library (with a little decoration) but named internal_L rather than just L
add_library(internal_L my.c sources.c)
target_include_directories(internal_L my_header_folder)
target_link_libraries(internal_L libraries_we_depend_on)

# this is the "wrapper", but defined as *INTERFACE* library
add_library(L INTERFACE)
target_link_libraries(L INTERFACE internal_L)
target_link_options(L INTERFACE "SHELL:-Wl,--whole-archive $<TARGET_FILE:internal_L> -Wl,--no-whole-archive")

# now use L in an executable
add_executable(my_executable some.c source.c)
target_link_libraries(my_executable PRIVATE L)

```

Can you confirm that this is the correct way to solve the problem (apart from the limitation to toolchains which support the `-Wl,--*whole-archive` options)? If not, can you suggest an alternative approach?

Kind regards  
Ingolf

---

<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: [June 17, 2022, 8:08am UTC](https://discourse.cmake.org/t/automatically-wrapping-a-static-library-in-whole-archive-no-whole-archive-when-used-during-linking/5883/2 "2022-06-17T08:08:59Z")

</div>

Starting with `CMake` 3.24 (currently in RC1), you can use [$\<LINK\_LIBRARY\>](https://cmake.org/cmake/help/v3.24/manual/cmake-generator-expressions.7.html#output-related-expressions) generator expression with feature `WHOLE_ARCHIVE` to achieve what you want:

```cmake
add_library(L INTERFACE)
target_link_libraries(L INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,internal_L>")

```

---

<div class="post-metadata">

### Author: ![ingolf](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/i/977dab/32.png) [@ingolf](https://discourse.cmake.org/u/ingolf)
#### Post date: [June 17, 2022, 8:14am UTC](https://discourse.cmake.org/t/automatically-wrapping-a-static-library-in-whole-archive-no-whole-archive-when-used-during-linking/5883/3 "2022-06-17T08:14:39Z")

</div>

@marc.chevrier, thank you for this hint. Unfortunately, we cannot switch to a RC. Would you recommend a different approach also to pre-3.24 CMake users (3.21.3 in our case)?

---

<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: [June 17, 2022, 8:30am UTC](https://discourse.cmake.org/t/automatically-wrapping-a-static-library-in-whole-archive-no-whole-archive-when-used-during-linking/5883/4 "2022-06-17T08:30:56Z")

</div>

Before `3.24`, there is no specific `CMake` feature to support this requirement.  
What you did seems reasonable, but be aware that the library `internal_L` will be repeated twice on the link command (one from `target_link_libraries` and one from `target_link_options`).

---

<div class="post-metadata">

### Author: ![JohannesWilde](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/j/d07c76/32.png) [@JohannesWilde](https://discourse.cmake.org/u/JohannesWilde)
#### Post date: [June 19, 2022, 10:50am UTC](https://discourse.cmake.org/t/automatically-wrapping-a-static-library-in-whole-archive-no-whole-archive-when-used-during-linking/5883/5 "2022-06-19T10:50:43Z")

</div>

From several search results I previously encountered the following solution. Using CMake 3.17 on a native build environment [Ubuntu 22.04 with gcc or Windows 10 with MinGW] this yielded the desired effects [correct linking and target-properties propagation]:

```auto
target_link_libraries(L
    INTERFACE -Wl,--whole-archive internal_L -Wl,--no-whole-archive
)

```

However using this approach failed [i.e. no `whole-archive` was present in the created compile command] with a cross-compile setup [on an Ubuntu 18.04 server with a gcc for a non-native architecture] - whereas the approach detailed in @ingolf 's question above seemed to work [`target_link_options`].

Does anyone have an idea as to why CMake might behave differently? Is this a CMake behaviour or is something else involved?

I would appreciate any ideas

Johannes
