Использование cmake для создания статической библиотеки статических библиотек - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь создать статическую библиотеку статических библиотек.Вот мой 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 должен иметь все эти библиотеки, связанные с ним.

ОБНОВЛЕНИЕ:

Похоже, я не могу связать статические библиотеки вместе, ни создать общую из статических.Как мне упаковать весь мой код в одну общую и одну статическую библиотеку?

1 Ответ

0 голосов
/ 26 апреля 2018

Первое, что нужно знать: никто не связывает статическую библиотеку - он использует архиватор (ar в Linux), который просто помещает все объектные файлы в один архив - libXXX.a

Этоне очень обычно создавать статическую библиотеку из других статических библиотек, но не невозможно (хотя я не знаю, как это сделать с помощью cmake, но если все остальное терпит неудачу, у вас все еще есть add_custom_command),

Предположим, у вас есть две статические библиотеки libA.a и libB.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 ожидает объектные файлы и не является интеллектуальнымДостаточно заглянуть в архивы, чтобы найти их.


Общие библиотеки связаны между собой.Кроме того, разделяемым библиотекам требуется независимый от позиции код, это означает, что все объектные файлы должны быть скомпилированы с параметрами -fPIC.

. Часто библиотека предоставляет две версии:

  1. статические, скомпилированные без-fPIC
  2. расшаренный, скомпилированный с -fPIC

Будучи скомпилированным без -fPIC, статическая версия немного более эффективна.Это также гарантирует, что статическая библиотека не используется как зависимость в общей библиотеке, что может привести к нарушениям One Definition Rule .

Как правило, общие библиотеки должны зависетьв других общих библиотеках, а не в статических.

Очевидно, что вы можете перекомпилировать все свои статические библиотеки с помощью -fPIC и связать их вместе в одну общую библиотеку - но я бы не рекомендовал это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...