2013-10-02 31 views
5
cmake 2.8 
gcc (GCC) 4.8.1 

Edycja ----------łącząc wspólną bibliotekę ze statyki z wykorzystaniem CMake

owijając statycznych bibliotek w whole-archive robót dla każdej biblioteki oprócz pjmedia-videodev Problem jest teraz, że gdy próbuję i kompilacji pojawia się następujący błąd.

cbar_factory_init': colorbar_dev.c:(.text+0x2a0): undefined reference to pjmedia_format_init_video' 

Witam,

I stworzyli wspólną bibliotekę i muszę połączyć tę bibliotekę z około 10 bibliotek statycznych. Następnie łączę mój plik wykonywalny z biblioteką współdzieloną.

Moje pytanie jest takie, że po uruchomieniu sprawię, że nie będzie się on łączyć, tak jak chce również statycznych bibliotek. Celem jest utworzenie opakowania dla bibliotek statycznych. Tak więc plik wykonywalny musi tylko łączyć się z 1 pojedynczą wspólną biblioteką. Ponieważ łączę bibliotekę współużytkowaną ze statyką, statyka automatycznie stanie się częścią kodu źródłowego biblioteki współdzielonej.

Tylko kod sippnety, aby było krótkie. W moim CMakeLists.txt który tworzy wspólną bibliotekę i łączy bibliotek statycznych:

add_library(app_module_sip SHARED app_module_sip_init.c) 

set(PJSIP_LIBRARIES 
    g7221codec 
    gsmcodec 
    ilbccodec 
    milenage 
    pj 
    pjlib-util 
    pjmedia 
    pjmedia-codec 
    pjmedia-audiodev 
    pjmedia-videodev 
    pjnath 
    pjsip 
    pjsip-simple 
    pjsip-ua 
    pjsua 
    portaudio 
    resample 
    speex 
    srtp 
) 

target_link_libraries(app_module_sip pthread m uuid nsl rt asound crypto ssl ${PJSIP_LIBRARIES}) 

Teraz moim CMakeLists.txt sprawia, że ​​plik wykonywalny

add_executable(app sip_test.c) 

target_link_libraries(app app_module_sip) 

jest to prawidłowe, co robię tutaj. Nie chcę łączyć pliku wykonywalnego z bibliotekami statycznymi. Tylko pojedyncza biblioteka współdzielona, ​​to jest moje opakowanie, do którego będę wywoływał funkcje.

To działa poprawnie, jeśli połączę wszystkie biblioteki ze statykami podczas wykonywania pliku wykonywalnego, ale to nie jest wynik, którego chcę.

Wielkie dzięki za wszelkie sugestie,

Odpowiedz

1
# Location for shared library 
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/libs) 

# Create shared library 
add_library(app_module_sip SHARED app_module_sip_init.c) 

# compile and link for 32 bit mode 
set_target_properties(app_module_sip PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") 

# PJSIP static libraries 
set(PJSIP_LIBRARIES 
    pjsua 
    pjsip-ua 
    pjsip-simple 
    pjsip 
    pjmedia-codec 
    pjmedia-videodev 
    pjmedia 
    pjmedia-audiodev 
    pjnath 
    pjlib-util 
    resample 
    milenage 
    srtp 
    gsmcodec 
    speex 
    ilbccodec 
    g7221codec 
    portaudio 
    pj 
) 

# Wrap the static libraries in to the shared library 
target_link_libraries(app_module_sip -Wl,--start-group ${PJSIP_LIBRARIES} -Wl,--end-group 
    m uuid nsl rt pthread asound crypto ssl) 

Trzeba owinąć bibliotek PJSIP będą następujące polecenie łącznik -Wl, - start-group * .a -Wl - end-grupa.

To rozwiązało mój problem.

+0

Kiedy łączę app_module_sip z myapp, CMake wydaje się dodawać wszystkie biblioteki wnuków, takie jak pjsua *, oprócz * app_module_sip, a zduplikowane obiekty komunikują statyczną inicjalizację, nie wspominając już o nadmiernym rozmiarze binarnym. – nodakai

3

próbowałem przetestować moje rozwiązanie, ale Twój CMakeLists.txt pracował dla mnie bez żadnych zmian. Mimo to, patrząc na to pytanie: Include static lib in dynamic lib, wydaje się, że należy spróbować

target_link_libraries(app_module_sip ... ssl -Wl,-whole-archive ${PJSIP_LIBRARIES} -Wl,-no_whole-archive) 

(przewinąć do końca, to długa linia)

+0

To zadziałało dla mnie. Jednak moja biblioteka statyczna, którą próbowałem połączyć, nie powiodła się z libpjmedia-videodev.a (colorbar_dev.o): W funkcji 'cbar_factory_init ': colorbar_dev.c :(. Text + 0x2a0): niezdefiniowane odwołanie do' pjmedia_format_init_video'. Jeśli jednak usunę bibliotekę statyczną pjmedia-videodev, wszystko kompiluje, buduje i uruchamia. Nie wiem, dlaczego ta biblioteka się nie powiodła. W tej chwili nie potrzebuję żadnych pracowników wideo, ale później będę go potrzebować. Dzieki za sugestie. – ant2009

2

To nie jest takie proste.

Możesz skorzystać z opcji "-Wl, - całe-archiwum" lub "-Wl, - eksportuj wszystkie symbole" w zależności od platformy, ale nie ma na to sposobu na wiele platform. Wszystko działa inaczej, a Windows odtwarza zupełnie inną grę za pomocą lib.exe.

Prawdopodobnie chcesz zrobić coś takiego:

http://www.mail-archive.com/[email protected]/msg01890.html

... i dodać obsługę specjalnie dla platform, które mają na celu wspieranie, po jednym na raz.

+0

@ Doug, ten artykuł był 2006 i -all i -nieważne już nie istnieje. Moja aktualna wersja ld to "GNU ld wersja 2.23.51.0.1-10.fc18" Chyba została usunięta w pewnym momencie. Dzięki. – ant2009

+0

@ ant2009 Nie, miałem na myśli, używaj IF ("$ {CMAKE_SYSTEM}" MECZE IRIX) ... JEŻELI (APPLE) ... JEŻELI (WIN32) ... itd. Ie. Musisz ręcznie określić różne flagi kompilacji dla każdej platformy, którą chcesz obsłużyć. Nie ma "ogólnego" sposobu robienia tego, który jest wieloplatformowy. – Doug