# Adding link libraries at build time

**URL:** <https://discourse.cmake.org/t/adding-link-libraries-at-build-time/7552>\
**Category:** Code\
**Created:** [February 27, 2023, 12:05pm UTC](https://discourse.cmake.org/t/adding-link-libraries-at-build-time/7552 "2023-02-27T12:05:02Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![jschwe](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jschwe/32/3206_2.png) [@jschwe](https://discourse.cmake.org/u/jschwe)\
**Post date:** [February 27, 2023, 12:05pm UTC](https://discourse.cmake.org/t/adding-link-libraries-at-build-time/7552/1 "2023-02-27T12:05:02Z")

</div>

Hi,

I’m currently maintaining [Corrosion](https://github.com/corrosion-rs/corrosion) which integrates Rusts cargo build system into CMake.  
When linking Rust static libraries into C/C++ code (managed by CMake), we also need to link some system libraries (e.g. `pthread`). Currently, the required libraries are hardcoded in corrosion, based on what is usually required for the target OS. Ideally though, we would like to ask `rustc` which libraries we need to link. `rustc` provides an option `--print native-static-libs` which prints a list of required libraries.

This list is produced during the actual build of the static library. Using a dummy demo project to get a list of libraries is also not sufficient in all cases, since `rustc` will actually take all dependencies into consideration and any `#[link]` attributes in the source code, which may specify libraries to link against. Build-scripts may also add additional libraries to the list of libraries that should be linked.

Is there any way that we could respect this list of required libraries, generated at build-time, and add them to the target CMake C/C++ executable via `target_link_libraries()`? From my understanding currently there is no way to do this in CMake, unless we would prebuild the Rust project at configure time.

---

<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:** [February 27, 2023, 2:40pm UTC](https://discourse.cmake.org/t/adding-link-libraries-at-build-time/7552/2 "2023-02-27T14:40:57Z")

</div>

One way you could do this is to add a link option of `@rspfile`. You probably want to do this as an `INTERFACE` on the Rust target and write it via some `POST_LINK` custom command on that target. Or add it to the custom command chain if it is already a chain of custom commands.

---

<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:** [February 27, 2023, 2:41pm UTC](https://discourse.cmake.org/t/adding-link-libraries-at-build-time/7552/3 "2023-02-27T14:41:50Z")

</div>

Note that because of the build-time discovery, libraries will be duplicated on the command line because sorting and filtering the link line requires generator-time knowledge which has been thrown away by then.

---

<div class="post-metadata">

**Author:** ![jschwe](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jschwe/32/3206_2.png) [@jschwe](https://discourse.cmake.org/u/jschwe)\
**Post date:** [February 27, 2023, 4:21pm UTC](https://discourse.cmake.org/t/adding-link-libraries-at-build-time/7552/4 "2023-02-27T16:21:34Z")

</div>

> One way you could do this is to add a link option of `@rspfile`

Thanks, that sounds useful! Is this `@rspfile` a Windows / MSVC specific linker option? I looked at the documentation for `ld` and couldn’t find anything which would allow me to load arguments from a file.

---

<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:** [February 27, 2023, 8:07pm UTC](https://discourse.cmake.org/t/adding-link-libraries-at-build-time/7552/5 "2023-02-27T20:07:42Z")

</div>

CMake uses the compiler frontend, so you actually want `gcc` and/or `clang` docs and they support response files. `ar` supports response files though according to its manpage.

---

<div class="post-metadata">

**Author:** ![jschwe](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jschwe/32/3206_2.png) [@jschwe](https://discourse.cmake.org/u/jschwe)\
**Post date:** [February 12, 2024, 6:40pm UTC](https://discourse.cmake.org/t/adding-link-libraries-at-build-time/7552/6 "2024-02-12T18:40:10Z")

</div>

It’s been a while, but I’d like to revive this topic. I’ve been [experimenting with response files](https://github.com/corrosion-rs/corrosion/pull/472), but I just can’t get it to work. I’m currently using something that boils down to

```cmake
target_link_options(${target_name}-static INTERFACE "@$<SHELL_PATH:${rsp_file}>" "LINKER:--verbose")

```

When I do this, the linker (ld) complains that it can’t find basic libraries like libc.

Excerpt:

```auto
attempt to open /usr/lib/x86_64-linux-gnu/libc.so failed
attempt to open /usr/lib/x86_64-linux-gnu/libc.a failed
...
attempt to open /usr/x86_64-linux-gnu/lib64/libc.so failed
attempt to open /usr/x86_64-linux-gnu/lib64/libc.a failed
attempt to open /usr/x86_64-linux-gnu/lib/libc.so failed
attempt to open /usr/x86_64-linux-gnu/lib/libc.a failed
/usr/bin/ld: cannot find -lc: No such file or directory

```

an `ls -l` on the same github action, does tell me that the files in question exist:

```auto
-rw-r--r-- 1 root root 283 Jan 2 13:22 /usr/lib/x86_64-linux-gnu/libc.so
-rw-r--r-- 1 root root 283 Jan 2 13:22 /usr/lib/x86_64-linux-gnu/libc.so

```

I’m wondering if this might have anything to do with me using `target_link_options()` instead of `target_link_libraries()`? I tried the latter, but it seems I cannot pass any `@` response file to `target_link_libraries()`.

---

<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:** [February 16, 2024, 2:20pm UTC](https://discourse.cmake.org/t/adding-link-libraries-at-build-time/7552/7 "2024-02-16T14:20:34Z")

</div>

What is in the `rsp_file`? Does the linker behave the same if you provide the flags on the command line directly (manually)?

---

<div class="post-metadata">

**Author:** ![jschwe](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jschwe/32/3206_2.png) [@jschwe](https://discourse.cmake.org/u/jschwe)\
**Post date:** [February 18, 2024, 9:02pm UTC](https://discourse.cmake.org/t/adding-link-libraries-at-build-time/7552/8 "2024-02-18T21:02:23Z")

</div>

Thanks a lot - Your comment prompted me to try hardcoding the values. Everything works fine when hardcoding the options via `target_link_options` and also when hardcoding the contents of the response file. Since I was essentially `printf` debugging before, it turns out the rsp file contained an ansi escape sequence before the end of the line, which was not visible when printing the contents via CMake.

Adding `--color=never` to the rustc invocation fixes my problem, although probably I could also try to improve my regex to handle the ansi escape sequence.

---

<div class="post-metadata">

**Author:** ![jschwe](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jschwe/32/3206_2.png) [@jschwe](https://discourse.cmake.org/u/jschwe)\
**Post date:** [February 18, 2024, 9:25pm UTC](https://discourse.cmake.org/t/adding-link-libraries-at-build-time/7552/9 "2024-02-18T21:25:29Z")

</div>

Now my only remaining question is:  
Is there any way to also get this working for MSVC?  
Judging by [this MSVC documentation](https://learn.microsoft.com/en-us/cpp/build/reference/at-specify-a-compiler-response-file?view=msvc-170) I’m suspecting it is currently not possible to add a compiler response file via CMake - at least it seems that cmake adds link options to the vcxproject file, while msvc only accepts response files “at the command line” (whatever that means in relation with CMake).

---

<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:** [February 19, 2024, 3:57am UTC](https://discourse.cmake.org/t/adding-link-libraries-at-build-time/7552/10 "2024-02-19T03:57:49Z")

</div>

I have no idea how to make Visual Studio do it if `target_link_options(tgt PRIVATE @rsp)` doesn’t work. The `Ninja` generators execute “at the command line”. MSBuild (inside of VS) does too, but is mediated through the `.vc*proj` files.
