# \`install()\`-ing a static library also requires installing an internal object library?

**URL:** <https://discourse.cmake.org/t/install-ing-a-static-library-also-requires-installing-an-internal-object-library/683>\
**Category:** Code\
**Created:** [February 21, 2020, 9:15pm UTC](https://discourse.cmake.org/t/install-ing-a-static-library-also-requires-installing-an-internal-object-library/683 "2020-02-21T21:15:55Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![alex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/alex/32/125_2.png) [@alex](https://discourse.cmake.org/u/alex)\
**Post date:** [February 21, 2020, 9:15pm UTC](https://discourse.cmake.org/t/install-ing-a-static-library-also-requires-installing-an-internal-object-library/683/1 "2020-02-21T21:15:55Z")

</div>

I have two directories, `src` and `src/runtime`, which each contain their own CMakeLists.txt. `src` contains my main target. `runtime` contains a large number of files which are (in a series of steps) transformed into `.cpp` files that export an array containing the bytes of the transformed resources.

Because these `.cpp` files are generated via `add_custom_command`, I cannot add them to my main target with `target_sources`. So instead, I add them to an OBJECT library and then link it to my main target with `target_link_libraries` in `src`.

This works well when I’m building my library as a **shared** library. But when I try to build it as a **static** library, the packaging system complains that I haven’t exported the internal OBJECT library. If I add it to the export set, then the generated imported target adds `-lmy_proj_runtime` to the linker lines of consuming projects, which is just wrong.

This is also a problem with 3rd-party dependencies that should be loaded via `find_dependencies` at Config time. It results in a linker line that reflects the names of the IMPORTED targets I created out of the variables the old CMake 2.8 libraries set.

What is the correct solution for this? Is there something about the CMake model I’m not understanding? Should I only link to these libraries via `$<BUILD_INTERFACE:...>`? Will that even work? It seems like a hack.

---

<div class="post-metadata">

**Author:** ![kyle.edwards](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/k/65b543/32.png) [@kyle.edwards](https://discourse.cmake.org/u/kyle.edwards)\
**Post date:** [February 21, 2020, 9:25pm UTC](https://discourse.cmake.org/t/install-ing-a-static-library-also-requires-installing-an-internal-object-library/683/2 "2020-02-21T21:25:27Z")

</div>

This is a gotcha when using object libraries. Instead of using `target_link_libraries()` to link to the object library, try the following:

```cmake
add_library(runtime OBJECT ${runtime_src})
add_library(mylib $<TARGET_OBJECTS:runtime>)

```

This causes the object files from `runtime` to be used as the sources for `mylib` (whether it be shared or static.) Since they’re already compiled, they’re just lumped into the library output as-is.

---

<div class="post-metadata">

**Author:** ![alex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/alex/32/125_2.png) [@alex](https://discourse.cmake.org/u/alex)\
**Post date:** [February 21, 2020, 10:03pm UTC](https://discourse.cmake.org/t/install-ing-a-static-library-also-requires-installing-an-internal-object-library/683/3 "2020-02-21T22:03:36Z")

</div>

Thanks! That seemed to work for the OBJECT library.

What about the imported targets I created for 3rd party dependencies? Those appear on the linker line too, but they look like MyProj\_dep, which obviously isn’t standard.

---

<div class="post-metadata">

**Author:** ![alex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/alex/32/125_2.png) [@alex](https://discourse.cmake.org/u/alex)\
**Post date:** [February 22, 2020, 1:45am UTC](https://discourse.cmake.org/t/install-ing-a-static-library-also-requires-installing-an-internal-object-library/683/4 "2020-02-22T01:45:32Z")

</div>

It seems that if I do that, then interface properties on the object library no longer propagate. Hm. I was able in my case to move those properties up to the parent library. But is there some way to get the best of both worlds?

---

<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 28, 2020, 8:06pm UTC](https://discourse.cmake.org/t/install-ing-a-static-library-also-requires-installing-an-internal-object-library/683/5 "2020-02-28T20:06:38Z")

</div>

You should be able to export the `OBJECT` library. I believe it just turns into an `INTERFACE` library when installed (unless `OBJECTS DESTINATION` is given). At least that was the plan when we started making them better CMake citizens.

Cc: @brad.king @robert.maynard

---

<div class="post-metadata">

**Author:** ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)\
**Post date:** [February 28, 2020, 8:17pm UTC](https://discourse.cmake.org/t/install-ing-a-static-library-also-requires-installing-an-internal-object-library/683/6 "2020-02-28T20:17:58Z")

</div>

Yes, installing and exporting an `OBJECT` library without any `OBJECTS DESTINATION` will turn it into an `INTERFACE` library. That can be used to propagate usage requirements to the application that your real library has transitively through its use of the object library. This is important when your real library is a static library because it can have link dependencies that come from object files in the object library, and only the object library target has the needed `INTERFACE_LINK_LIBRARIES` on it.

See also discussion in [CMake Issue 15415](https://gitlab.kitware.com/cmake/cmake/issues/15415#note_333595).
