如何在 CMake 中使用对象库创建共享库

How to create a shared library using object library in CMake

我有两个共享库,每个共享库都有自己的 CMakeLists.txt。目录结构是这样的

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

目前,我可以同时构建主库和子库(比如 main.so 和 sub.so)。

两者的 CMakeLists.txt 如下所示。

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)

现在我希望子库的目标文件或符号也包含在主库中,这样用户即使不link他们的应用程序也可以单独使用主库子库。

我是 CMake 的新手,我试图从 sub_dir 和 link 中的所有源文件创建一个对象库到我的 mainlib。

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

但是它给我错误。

(add_library) No SOURCES given to target: mainlib

如何在 sub_dir 中创建对象库并将其添加到子库和主库中。有没有更好的方法来做到这一点。谢谢。

要使用 OBJECT 库,link。这并没有做任何实际的 linking——没有对象库的“东西”,它只是 CMake 知道的对象文件的集合——而是将对象文件放在目标中:

target_link_libraries(mainlib PRIVATE sublib)

这是一个完整的例子(它创建了源文件 one.cpptwo.cpp 所以它完全是 self-contained):

cmake_minimum_required(VERSION 3.18)
project(example)
if(NOT EXISTS one.cpp)
  file(WRITE one.cpp "int x;")
endif()
if(NOT EXISTS two.cpp)
  file(WRITE two.cpp "int y;")
endif()
add_library(sublib OBJECT one.cpp)
add_library(mainlib SHARED two.cpp)
target_link_libraries(mainlib PRIVATE sublib)

我能够通过为 suddirectory 中的对象库设置 PARENT_SCOPE 来让它工作。对原始代码的修改如下所示。

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)

感谢您的回复。