Cmake:链接到静态内部库而不导出它

Cmake: linking to static internal library without exporting it

本文关键字:内部 链接 静态 Cmake      更新时间:2023-10-16

我有一个具有此结构的项目:

/path/to/my/project
├── CMakeLists.txt
├── internal-libs
│   ├── internal-lib1
├── libs
│   ├── lib1
│   ├── lib2

lib1是一个静态库。

lib2是一个静态库。

internal-lib1是一个静态库。

lib2

静态链接到 lib2 和 internal-lib1。 lib1lib2将被出口,但internal-lib1将被抛在后面。对于链接,我有:

target_link_libraries(lib2 PRIVATE internal-lib1)
target_link_libraries(lib2 PRIVATE lib1)

我的理解是,因为我是静态和私密链接的,所以有关 internal-lib1 的所有信息都将包含在 lib2 中,并且我不必将 internal-lib1 导出到外部世界。

但是,当我尝试在客户端程序中使用它时,出现错误:

/usr/bin/ld cannot find -llib-internal1
collect2: error: ld returned 1 exit status

在我生成的导出配置文件中,我有:

# Create imported target lib2
add_library(lib2 STATIC IMPORTED)
set_target_properties(lib2 PROPERTIES
INTERFACE_LINK_LIBRARIES "$<LINK_ONLY:lib1>;**$<LINK_ONLY:internal-lib1>**"
)
# Create imported target lib1
add_library(lib1 STATIC IMPORTED)

我是否误解了静态链接,或者我的设置有问题?我正在使用 cmake 3.2.2。我的目标包括所有是私人的。我不明白为什么INTERFACE_LINK_LIBRARIES填充了条目以及LINK_ONLY的含义。

p.s. 实际上 lib1 和 lib2 应该是共享库,但我什至无法让静态版本工作,所以为了简单起见,我在这里描述可导出库的静态情况。

对于静态库lib1lib2,CMake 命令

target_link_libraries(lib2 PRIVATE lib1)

并不意味着库lib1在链接时lib2复制到库。PRIVATE 关键字仅在另一个库链接到lib2lib1影响库的传递使用要求。

若要让 CMake 在链接时将lib1合并到lib2中,请使用libtoolPOST_BUILD操作:

add_custom_command(TARGET lib2 POST_BUILD
    COMMAND /usr/bin/libtool -static -o $<TARGET_FILE:lib2>
    $<TARGET_FILE:lib2> $<TARGET_FILE:lib1>

在这种情况下,无需将lib1链接到lib2 target_link_libraries .

一种选择是创建对象库而不是静态库:

add_library(foo OBJECT foo.cpp)
add_executable(baz $<TARGET_OBJECTS:foo> baz.cpp)

您可以在此处找到有关此功能的更多文档:https://cgold.readthedocs.io/en/latest/rejected/object-libraries.html