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

时间:2016-03-23 14:58:56

标签: c++ linker cmake

我有一个具有这种结构的项目:

/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应该是共享库,但我甚至无法使静态版本工作,所以为了简单起见,我在描述可导出库的静态情况。

2 个答案:

答案 0 :(得分:5)

CMake命令

target_link_libraries(lib2 PRIVATE lib1)

并不意味着在链接时将库lib1复制到库lib2。当另一个库链接到PRIVATE时,lib1关键字仅影响库lib2的{​​{3}}。

要在链接时让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>

在这种情况下,您无需将lib1lib2target_link_libraries相关联。

答案 1 :(得分:0)

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

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

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