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

Modifica ----------collegando una libreria condivisa con statica usando CMake

avvolgendo le librerie statiche in whole-archive lavori per ogni libreria, tranne il pjmedia-videodev Il problema ora è che quando provo e costruisco ottengo il seguente errore.

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

Ciao,

Ho creato una libreria condivisa e ho bisogno di collegare quella biblioteca con circa 10 librerie statiche. Quindi collego il mio eseguibile con la libreria condivisa.

La mia domanda è che quando eseguo make non riesce a collegarsi come vuole anche le librerie statiche. Lo scopo è creare un wrapper per le librerie statiche. Quindi l'eseguibile deve solo collegarsi con 1 singola libreria condivisa. Mentre collego la libreria condivisa con la statica, la statica diventerà automaticamente parte del codice sorgente della libreria condivisa.

Solo codice sippnet per renderlo breve. Nel mio CMakeLists.txt che crea la libreria condivisa e collega le librerie statiche:

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}) 

Ora la mia CMakeLists.txt che rende l'eseguibile

add_executable(app sip_test.c) 

target_link_libraries(app app_module_sip) 

È questo corretto quello che sto facendo qui. Non voglio collegare l'eseguibile con le librerie statiche. Solo la singola libreria condivisa in quanto è il mio wrapper in cui chiamerò le funzioni.

Fa link ok, se collego tutte le librerie statiche quando eseguo l'eseguibile, ma questo non è il risultato che voglio.

Molte grazie per qualsiasi suggerimento,

risposta

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) 

bisogno di avvolgere le librerie PJSIP sarà il seguente comando linker -Wl, - start-gruppo * .a -Wl, - gruppo terminale.

Questo ha risolto il mio problema.

+0

Quando collego app_module_sip a myapp, CMake sembra aggiungere tutte le librerie di nipoti come pjsua * oltre a * app_module_sip, e gli oggetti duplicati rovinano l'inizializzazione statica, per non parlare delle dimensioni binate. – nodakai

3

ho cercato di testare la mia soluzione, ma il vostro CMakeLists.txt lavorato per me senza alcuna modifica. Eppure, guardando a questa domanda: Include static lib in dynamic lib, sembra che si dovrebbe provare

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

(scorrere fino alla fine, si tratta di una lunga serie)

+0

Questo ha funzionato per me. Tuttavia, la mia libreria statica che ho provato a collegare non è riuscita con libpjmedia-videodev.a (colorbar_dev.o): nella funzione 'cbar_factory_init ': colorbar_dev.c :(. Testo + 0x2a0): riferimento non definito a' pjmedia_format_init_video'. Tuttavia, se rimuovo la libreria statica pjmedia-videodev, tutto viene compilato, compilato ed eseguito. Non sono sicuro del motivo per cui quella libreria è fallita. Al momento non ho bisogno di personale video, ma in seguito ne avrò bisogno. Grazie per il suggerimento. – ant2009

2

Non è così semplice.

È possibile utilizzare '-Wl, - whole-archive' o '-Wl, -export-all-symbols' a seconda della piattaforma, ma non esiste un valido metodo multipiattaforma per farlo. Tutto lo fa in modo diverso, e Windows gioca un gioco completamente diverso usando lib.exe.

probabilmente si vuole fare qualcosa di simile:

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

... e aggiungere il supporto specifico per le piattaforme che si desidera supportare, uno alla volta.

+0

@ Doug, quell'articolo era il 2006 e il -all e -notall non esiste più. La mia attuale versione ld è 'GNU ld versione 2.23.51.0.1-10.fc18' Suppongo che sia stata rimossa ad un certo punto. Grazie. – ant2009

+0

@ ant2009 no, intendevo usare IF ("$ {CMAKE_SYSTEM}" MATCHES IRIX) ... SE (APPLE) ... SE (WIN32) ... ecc. Ie. Devi specificare manualmente i diversi flag di compilazione per ciascuna piattaforma che vuoi supportare. Non esiste un modo "generale" per fare ciò che è multipiattaforma. – Doug

Problemi correlati