2013-01-02 12 views
27

Ho un programma e di una libreria statica:Come forzare gcc per collegare una libreria statica inutilizzato

// main.cpp 
int main() {} 

// mylib.cpp 
#include <iostream> 
struct S { 
    S() { std::cout << "Hello World\n";} 
}; 
S s; 

voglio collegare la libreria statica (libmylib.a) per l'oggetto programma (main.o), anche se quest'ultimo non usa alcun simbolo del primo direttamente.

I seguenti comandi non sembrano al lavoro con g++ 4.7. Saranno eseguito senza errori o avvisi, ma a quanto pare non sarà collegata libmylib.a:

g++ -o program main.o -Wl,--no-as-needed /path/to/libmylib.a 

o

g++ -o program main.o -L/path/to/ -Wl,--no-as-needed -lmylib 

Avete qualche idea migliore?

+0

AFAIK, '-lmylib'. – chris

+0

@chris ho reso la domanda più chiara -lmylib non modifica la situazione – Martin

+2

Le statiche possono essere inizializzate ovunque prima di main fino alla prima chiamata a una funzione all'interno di quella unità di traduzione ... il che significa che la mai istanziazione s è valida secondo lo standard, dato che non viene mai chiamata alcuna funzione da quella unità di traduzione. –

risposta

43

Utilizzare l'opzione di collegamento --whole-archive.

Le librerie che arrivano a dopo il nella riga di comando non avranno i simboli non referenziati scartati. È possibile riprendere il normale comportamento di collegamento aggiungendo --no-whole-archive dopo queste librerie.

Nel tuo esempio, il comando sarà:

g++ -o program main.o -Wl,--whole-archive /path/to/libmylib.a 

In generale, sarà:

g++ -o program main.o \ 
    -Wl,--whole-archive -lmylib \ 
    -Wl,--no-whole-archive -llib1 -llib2 
+0

Qualcuno sa se c'è un controllo più preciso di questo, come usare la visibilità del DSO? Sto pensando di taggare alcune funzioni per essere forzato. Vedi https://gcc.gnu.org/wiki/Visibility – csl

+3

L'utente dovrebbe comunque aggiungere '-Wl, -no-whole-archive' alla fine. Come [man ld] (http://man7.org/linux/man-pages/man1/ld.1.html) dice: * "In secondo luogo, non dimenticare di usare' -Wl, -no-whole-archive 'dopo la vostra lista di archivi, perché gcc aggiungerà una propria lista degli archivi al tuo link e non si può decidere questo flag per influenzare quelle pure." * – Sasha

+0

@csl, forse http://stackoverflow.com/a/43894291/192373 risponde alla tua domanda? –

4

mi piacciono le altre risposte meglio, ma qui è un'altra "soluzione".

  1. Utilizzare il comando ar per estrarre tutti i file .o dall'archivio.

    cd mylib ; ar x /path/to/libmylib.a 
    
  2. quindi aggiungere tutti i file .o al comando linker

    g++ -o program main.o mylib/*.o 
    
1

Se c'è una funzione specifica nella libreria statica che viene spogliato dal linker come non utilizzato, ma si ne hai davvero bisogno (un esempio comune è la funzione JNI_OnLoad()), puoi forzare il linker a tenerlo (e naturalmente, tutto il codice che viene chiamato da questa funzione). Aggiungi -u JNI_OnLoad al comando di collegamento.

Problemi correlati