c++cmakebuildlinker

How to create a shared library using object library in CMake


I have two shared libraries each one having its own CMakeLists.txt. The directory structure is like this.

main_dir
|--- subdir
|    |--- src1.cpp
|    |--- src2.cpp
|    |--- src3.cpp
|    |--- CMakeLists.txt
|--- src11.cpp
|--- CMakeLists.txt

Currently, I am able to build both main library and sub library (say main.so and sub.so).

The CMakeLists.txt for both looks as below.

main_dir/CMakeLists.txt

option(BUILD_SHARED_LIBS "Build the shared library" ON)

if(BUILD_SHARED_LIBS)
  add_library(mainlib SHARED)
endif()

target_sources(mainlib PRIVATE
  src11.cpp
)

add_subdirectory(subdir)

subdir/CMakeLists.txt

option(BUILD_SHARED_LIBS "Build the shared library" ON)

if(BUILD_SHARED_LIBS)
  add_library(sublib SHARED)
endif()

target_sources(sublib PRIVATE
  src1.cpp
  src2.cpp
  src3.cpp)

Now I want the object file or symbols of sub library to be included in the main library as well, so that users can still use the main library alone even if they don't link their application to the sub library.

I'm new to CMake and I was trying to create an object library out of all source files in the sub_dir and link this to my mainlib.

add_library(subarchive OBJECT src1.cpp src2.cpp src3.cpp)
target_sources(mainlib INTERFACE $<TARGET_OBJECTS:subarchive>)

But It gives me error.

(add_library) No SOURCES given to target: mainlib

How can I create an object library in sub_dir and add it to both sublib and mainlib. Is there any better way to do this. Thanks.


Solution

  • I was able to get it working by setting PARENT_SCOPE for the object library in the suddirectory. The modifications to the original code look like this.

    main_dir/CMakeLists.txt

    set(SUBARCHIVE_OBJECTS)
    
    add_subdirectory(subdir)
    target_link_libraries(mainlib private ${SUBARCHIVE_OBJECTS}
    

    subdir/CMakeLists.txt

    add_library(subarchive OBJECT src1.cpp src2.cpp src3.cpp)
    list(APPEND SUBARCHIVE_OBJECTS $<TARGET_OBJECTS:subarchive>)
    set(SUBARCHIVE_OBJECTS ${SUBARCHIVE_OBJECTS} PARENT_SCOPE)
    

    Thanks for the responses.