Question: Is it possible to join multiple object libraries into a single larger object library?
Consider the following simple project. libA.cpp is compiled into an object library LibA.Obj, and libB.cpp is compiled into an object library LibB.Obj. I want to have an object library, LibAB.Obj, that consists of both LibA.Obj and LibB.Obj, and I want to link against it to produce a single shared library.
MyProject
├── CMakeLists.txt
└── src
├── libA.cpp
└── libB.cpp
If I want to link two libraries, A and B, into a single unit, I can do that by declaring them as object libraries:
cmake_minimum_required(VERSION 3.21)
project(ObjectLibExample)
add_library(LibA.Obj OBJECT src/libA.cpp)
add_library(LibB.Obj OBJECT src/libB.cpp)
add_library(LibAB SHARED $<TARGET_OBJECTS:LibA.Obj> $<TARGET_OBJECTS:LibB.Obj>)
This works as expected, and everything builds.
For reasons I will soon explain, I would like to merge multiple object libraries together into a single unit:
cmake_minimum_required(VERSION 3.21)
project(ObjectLibExample)
add_library(LibA.Obj OBJECT src/libA.cpp)
add_library(LibB.Obj OBJECT src/libB.cpp)
# Using LibAB.Obj as a source should be equivilant to using both LibA.Obj and LibB.Obj
add_library(LibAB.Obj OBJECT $<TARGET_OBJECTS:LibA.Obj> $<TARGET_OBJECTS:LibB.Obj>)
add_library(LibAB SHARED $<TARGET_OBJECTS:LibAB.Obj>)
Here, LibAB.Obj should be an object library collecting the sources of both LibA.Obj and LibB.Obj.
For some reason, CMake acts as though LibAB.Obj provides no sources, and the build fails.
- Why does this happen?
- Is this a bug?
- What workarounds are there?
Motivation / Background
I am currently working on re-organizing an existing project to have a modular structure. It will have modules A, B, and C, each of which will have submodules.
You can imagine the directory structure looking like this:
MyProject
├── A
│ ├── A1
│ ├── A2
│ └── A3
├── B
│ ├── B1
│ ├── B2
│ └── B3
└── C
├── C1
├── C2
└── C3
Each submodule represents a library that forms a part of a greater whole, and the build system should link everything together into a single library at the end.
The reason for this structure is twofold:
- each submodule forms a cohesive unit. It has it's own tests, benchmarks, and example code
- submodules should provide a clean API for their functionality, even if the internals are kind of hairy.
For example, MyProject/A/A1 looks like this:
MyProject/A/A1
├── bench
├── CMakeLists.txt
├── examples
├── src
└── test
My initial plan was to have each module contain an object library linking all of it's respective submodules, with all modules being statically linked together at root to produce a single library, MyProject.so.
Each submodule would also produce a library specific to that submodule (eg, MyProject/A/A1 would produce MyProject.A.A1.so), against which tests, benchmark code, and examples would be linked. This would allow faster iteration, without needing to re-build the entire project.
Unfortunately, this initial approach failed, for the reasons discussed above.

According to the documentation of
add_library(OBJECT):You haven't provided any sources that would compile, so a fatal error indicating that the object library isn't used in the intended way is expected.
A workaround possible starting cmake 3.12 would be to create an
INTERFACElibrary and linking the object libraries withINTERFACEvisibility.This does prevent you from using
$<TARGET_OBJECTS:LibAB.Obj>though.