我有一个具有这种结构的项目:
/path/to/my/project
├── CMakeLists.txt
├── internal-libs
│ ├── internal-lib1
├── libs
│ ├── lib1
│ ├── lib2
lib1
是一个静态库。
lib2
是一个静态库。
internal-lib1
是一个静态库。
lib2静态链接到lib2和internal-lib1。将导出lib1
和lib2
,但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应该是共享库,但我甚至无法使静态版本工作,所以为了简单起见,我在描述可导出库的静态情况。
答案 0 :(得分:5)
CMake命令
target_link_libraries(lib2 PRIVATE lib1)
并不意味着在链接时将库lib1
复制到库lib2
。当另一个库链接到PRIVATE
时,lib1
关键字仅影响库lib2
的{{3}}。
要在链接时让CMake将lib1
合并到lib2
,请使用libtool
和POST_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
相关联。
答案 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