使用cmake构建静态库的静态库

卢卡斯·扎内拉(Lucas Zanella)

我正在尝试创建一个静态库的静态库。这是我的CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

project(myRtspClient)

add_subdirectory(../third_party/Base64_live555 base64_live555)
add_subdirectory(../third_party/md5 md5)
add_subdirectory(../third_party/JRTPLIB jrtplib)

include_directories(include)
include_directories(../third_party/Base64_live555/include)
include_directories(../third_party/md5/include)
include_directories(jrtplib/src)
include_directories(../third_party/JRTPLIB/src)

file(GLOB SOURCES "*.cpp")

add_library(myRtspClient STATIC ${SOURCES})

add_library(libmd5 STATIC IMPORTED)
SET_PROPERTY(TARGET libmd5 PROPERTY IMPORTED_LOCATION ./md5/libmd5.a)

add_library(libbase64_live555 STATIC IMPORTED)
SET_PROPERTY(TARGET libbase64_live555 PROPERTY IMPORTED_LOCATION ./base64_live555/libbase64_live555.a)

add_library(libjrtp STATIC IMPORTED)
SET_PROPERTY(TARGET libjrtp PROPERTY IMPORTED_LOCATION ./jrtplib/src/librtp.a)

target_link_libraries(myRtspClient libmd5 libbase64_live555 libjrtp)
#install(TARGETS myRtspClient DESTINATION /usr/lib)

如果您想查看整个图片:https : //github.com/lucaszanella/myRtspClient/blob/8658dbcb8ed071b8d2649a471455f57f268932f4/myRtspClient/CMakeLists.txt

如您所见,我正在尝试myRtspClient通过与链接来创建目标libmd5 libbase64_live555 libjrtp由于cmake没有错误,即使我这样做

target_link_libraries(myRtspClient eewgg dsgsg dgsgsdgsg)

我不确定这是什么错误。这些库位于我指出的位置。但是,我不知道它们是否在第一次编译中。虽然我尝试了第二次,但是谁知道...

因此,继续...我尝试了很多SET_PROPERTY类似的方法:

SET_PROPERTY(TARGET libbase64_live555 PROPERTY IMPORTED_LOCATION ./base64_live555/libbase64_live555.a)

SET_PROPERTY(TARGET libbase64_live555 PROPERTY IMPORTED_LOCATION ./base64_live555)

SET_PROPERTY(TARGET libbase64_live555 PROPERTY IMPORTED_LOCATION base64_live555/libbase64_live555.a)

当我examples尝试构建时common_example.cpp(如有必要,请参见上面链接中的源代码树),我这样做:

g++ common_example.cpp -I ../myRtspClient/include ../myRtspClient/libmyRtspClient.a

但是我得到这样的链接错误:

utils.cpp:(.text+0x2f4): undefined reference to `MD5Init(MD5_CTX*)'
utils.cpp:(.text+0x316): undefined reference to `MD5Update(MD5_CTX*, unsigned char*, unsigned int)'
utils.cpp:(.text+0x32c): undefined reference to `MD5Final(MD5_CTX*, unsigned char*)'
../myRtspClient/libmyRtspClient.a(MediaSession.cpp.o): In function `MyRTPSession::MyRTPSession()':
MediaSession.cpp:(.text._ZN12MyRTPSessionC2Ev[_ZN12MyRTPSessionC5Ev]+0x1e): undefined reference to `jrtplib::RTPSession::RTPSession(jrtplib::RTPRandom*, jrtplib::RTPMemoryManager*)'
../myRtspClient/libmyRtspClient.a(myRtpSession.cpp.o): In function `MyRTPSession::IsError(int)':
myRtpSession.cpp:(.text+0x48): undefined reference to `jrtplib::RTPGetErrorString[abi:cxx11](int)'
../myRtspClient/libmyRtspClient.a(myRtpSession.cpp.o): In function `MyRTPSession::MyRTP_SetUp(MediaSession*)':
myRtpSession.cpp:(.text+0x1b5): undefined reference to `jrtplib::RTPSessionParams::RTPSessionParams()'
myRtpSession.cpp:(.text+0x25c): undefined reference to `jrtplib::RTPSession::Create(jrtplib::RTPSessionParams const&, jrtplib::RTPTransmissionParams const*, jrtplib::RTPTransmitter::TransmissionProtocol)'

链接过程中我在做什么错?libMyRtspClient应该将所有这些库链接到它。

更新:

似乎我无法将静态库链接在一起,也无法从静态库创建共享库。如何将所有代码打包到一个共享库和一个静态库中?

ad

首先要知道的是:没有链接静态库-人们使用的是归档器(ar在Linux上),该归档器只是将所有目标文件放入一个归档中-libXXX.a

从其他静态库构造一个静态库不是很平常,但并非没有可能(尽管我不知道如何使用cmake精确地做到这一点,但是如果其他所有方法都失败了,您仍然可以使用add_custom_command)。

假设您有两个静态库libA.alibB.a并且想将它们合并到一个组合库中libALL.a最直接的方法是解压缩两个归档文件(记住静态库毕竟只是归档文件),并将所有解压缩的目标文件打包到新的归档/静态库中libALL.a有关使用的选项的更多信息,请参考的手册页ar) :

ar -x libA.a
ar -x libB.a
ar -crs libALL.a *.o

另一种可能是使用mri-script作为ar,使用它可以避免所有未打包的目标文件都放在周围(并且更健壮,因为并非所有目标文件都具有*.o-extension):

ar -M <<EOM
    CREATE libALL.a
    ADDLIB libA.a
    ADDLIB libB.a
    SAVE
    END
EOM

有些人还跑了

ar -s libALL.a 

或同等学历

ranlib libALL.a 

以确保创建了存档索引(这是将静态库与简单存档区分开的唯一内容),但是默认情况下会进行构建。

还有一点需要注意:直观(并且更类似于VisualS tudio命令lib.exe /OUT:libALL.lib libA.lib libB.lib

ar -crs libALL.a libA.a libB.a

不会生成可供链接器使用的存档-ar需要目标文件,并且不够聪明,无法查看存档以找到它们。


共享库已链接。此外,共享库需要位置无关代码,这意味着所有目标文件都必须使用options进行编译-fPIC

通常,一个库提供两个版本:

  1. 静态的,编译时不带 -fPIC
  2. 共享,与 -fPIC

如果不使用进行编译-fPIC,则静态版本的效率会略高一些。它还确保了静态库不会在共享库中用作依赖项,否则可能导致违反“一个定义规则”

根据经验,共享库应依赖于其他共享库,而不是静态库。

显然,您可以使用重新编译所有静态库,-fPIC并将它们链接到一个共享库中,但是我不建议这样做。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章