I would like to create a single library from objects from multiple sub-directories, each one containing their own CMakeLists.txt with OBJECT library trick to have multiple t
Several OBJECT libraries can be incorporated into one INTERFACE library:
# Create lib1 OBJECT library with some sources, compile flags and so.
add_library(lib1 OBJECT ...)
# Create lib2 OBJECT library with some sources, compile flags and so.
add_library(lib2 OBJECT ...)
# Create INTERFACE library..
add_library(libs INTERFACE)
# .. which combines OBJECT libraries
target_sources(libs INTERFACE $<TARGET_OBJECTS:lib1> $<TARGET_OBJECTS:lib2>)
Resulted library can be used with standard target_link_libraries
:
add_library(mainLib <some-source>)
target_link_libraries(mainLib libs)
It is possible to combine INTERFACE libraries futher:
# Create libs_another INTERFACE library like 'libs' one
add_library(libs_another INTERFACE)
..
# Combine 'libs' and 'libs_another' together
add_library(upper_level_libs INTERFACE)
target_link_libraries(upper_level_libs INTERFACE libs libs_another)
Resulted libraries' "chain" could be of any length.
While this way for combination of OBJECT libraries looks hacky, it is actually allowed by CMake documentation:
Although object libraries may not be named directly in calls to the
target_link_libraries()
command, they can be "linked" indirectly by using an Interface Library whose INTERFACE_SOURCES target property is set to name$<TARGET_OBJECTS:objlib>
.
I just collect objects from all places using set
with PARENT_SCOPE
.
root CMakeLists.txt:
set(OBJECTS)
add_subdirectory(lib1)
add_subdirectory(lib2)
add_library(lib STATIC ${OBJECTS})
CMakeLists.txt in subdirectories:
add_subdirectory(lib11)
add_library(${PROJECT_NAME} OBJECT src1.c)
list(APPEND OBJECTS $<TARGET_OBJECTS:${PROJECT_NAME}>)
set(OBJECTS ${OBJECTS} PARENT_SCOPE)