# Combine static libraries

**URL:** https://discourse.cmake.org/t/combine-static-libraries/14172
**Category:** Usage
**Created:** [May 28, 2025, 12:31am UTC](https://discourse.cmake.org/t/combine-static-libraries/14172 "2025-05-28T00:31:37Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![ramcdona](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ramcdona/32/2439_2.png) [@ramcdona](https://discourse.cmake.org/u/ramcdona)
#### Post date: [May 28, 2025, 12:31am UTC](https://discourse.cmake.org/t/combine-static-libraries/14172/1 "2025-05-28T00:31:37Z")

</div>

I’ve seen a bunch of related questions here and across the internet. However, most are pretty old and/or have different circumstances. So apologies for the potential repeat.

I have a project that organizes its files into several directories – each resulting in a static library. All of these libs are linked together with a main() to build the primary executable.

I also would like to combine those libs together into a single library – so users of my API can deal with just a single file. Some of my library users are not CMake users, so providing a single static library and an includes directory with what they need is the best way to go.

This seems like a very basic feature that CMake apparently lacks. I’ve found many old solutions, but some are limited (say only for OBJECT libraries), or are not cross-platform. I need a solution that works for Linux/Mac/Windows – gcc/clang/msvc.

Any help is appreciated,

Rob

---

<div class="post-metadata">

### Author: ![JRR](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/j/ecccb3/32.png) [@JRR](https://discourse.cmake.org/u/JRR)
#### Post date: [June 18, 2025, 3:10pm UTC](https://discourse.cmake.org/t/combine-static-libraries/14172/2 "2025-06-18T15:10:19Z")

</div>

@ramcdona, did you find an elegant solution to your liking? If so could you share it?

My shop has done static library combos at times. It works, but I also question if there is a better _CMake_ way of doing it.

We ended up creating two calling hierarchies. One for doing it on Windows (MSVC) and another for doing it on Linux (gcc), and a common interface call that would branch to Windows or Linux based on the machine we are running on. It “works” for the setup we have but we don’t do, and with this logic we cannot support, cross compilation.’

---

<div class="post-metadata">

### Author: ![vito.gamberini](https://discourse.cmake.org/user_avatar/discourse.cmake.org/vito.gamberini/32/4376_2.png) [@vito.gamberini](https://discourse.cmake.org/u/vito.gamberini)
#### Post date: [June 18, 2025, 7:22pm UTC](https://discourse.cmake.org/t/combine-static-libraries/14172/3 "2025-06-18T19:22:29Z")

</div>

This is a long-running CMake request, the related issue is: [https://gitlab.kitware.com/cmake/cmake/-/issues/19224](https://gitlab.kitware.com/cmake/cmake/-/issues/19224)

---

<div class="post-metadata">

### Author: ![ramcdona](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ramcdona/32/2439_2.png) [@ramcdona](https://discourse.cmake.org/u/ramcdona)
#### Post date: [June 19, 2025, 11:52pm UTC](https://discourse.cmake.org/t/combine-static-libraries/14172/4 "2025-06-19T23:52:19Z")

</div>

Thanks for the reply @JRR

I haven’t found a solution yet.

Fortunately, I don’t need to support cross compilation.

I do need to support MacOS too – and many of the solutions I’ve seen online rely on GNU ar behavior that BSD ar does not have.

---

<div class="post-metadata">

### Author: ![ramcdona](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ramcdona/32/2439_2.png) [@ramcdona](https://discourse.cmake.org/u/ramcdona)
#### Post date: [June 20, 2025, 12:11am UTC](https://discourse.cmake.org/t/combine-static-libraries/14172/5 "2025-06-20T00:11:38Z")

</div>

@vito.gamberini Thanks for the reply.

The link you sent looks close, but it seems to start from a single target created with add\_library().

In my situation, I’d like to bundle several targets created with add\_library() – and ideally also several static libraries from outside my primary CMake project.

I have all of these in a list that I otherwise send as an argument to target\_link\_libraries( tgt ${lib\_list} ).

I don’t see how to use the linked solution in this situation.

---

<div class="post-metadata">

### Author: ![vito.gamberini](https://discourse.cmake.org/user_avatar/discourse.cmake.org/vito.gamberini/32/4376_2.png) [@vito.gamberini](https://discourse.cmake.org/u/vito.gamberini)
#### Post date: [June 20, 2025, 2:22pm UTC](https://discourse.cmake.org/t/combine-static-libraries/14172/6 "2025-06-20T14:22:58Z")

</div>

They’re the same, you want to call `ar` on static libraries to bundle them together. Whether those are system libraries or libraries created in the build is irrelevant to CMake.

The existing answer is to build the libraries you want to bundle as object libraries, then when they’re linked together a single archive is created with everything inside it.

CMake doesn’t have an abstraction for calling the archiver on static libraries to bundle them. It’s a known gap in the operations it supports.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [June 20, 2025, 2:41pm UTC](https://discourse.cmake.org/t/combine-static-libraries/14172/7 "2025-06-20T14:41:12Z")

</div>

The `target_sources()` command can be used to add sources to a target after the target has been defined.

This may be used to add sources in different subdirectories to build only one static library with all sources in a project tree.

---

<div class="post-metadata">

### Author: ![JRR](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/j/ecccb3/32.png) [@JRR](https://discourse.cmake.org/u/JRR)
#### Post date: [June 20, 2025, 2:42pm UTC](https://discourse.cmake.org/t/combine-static-libraries/14172/8 "2025-06-20T14:42:02Z")

</div>

@ramcdona, I _think_ we did it on OSX long ago before we dropped its support. I thought we used `ar` even on OSX or maybe we used `libtool`, but that is a really old dusty memory – and a few SCMs and code purges ago.
