2013-01-02 12 views
27

Mam program i statyczną bibliotekę:Jak zmusić gcc połączyć nieużywany biblioteka statyczna

// main.cpp 
int main() {} 

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

chcę połączyć statycznej biblioteki (libmylib.a) do obiektu programu (main.o), choć ten ostatni nie używa żadnego symbolu tego pierwszego bezpośrednio.

Następujące polecenia nie wydają się być zgodne z g++ 4.7. Będą one działać bez jakichkolwiek błędów lub ostrzeżeń, ale widocznie libmylib.a nie będą powiązane:

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

lub

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

Czy macie jakieś lepsze pomysły?

+0

AFAIK, '-lmylib'. – chris

+0

@chris Ulepszyłem pytanie -lmylib nie zmienia sytuacji – Martin

+2

Statyczne s można zainicjować w dowolnym miejscu od przed głównym do pierwszego wywołania funkcji w tej jednostce tłumaczeniowej ... to znaczy, że nigdy nie jest tworzone wystąpienie s zgodnie ze standardem, biorąc pod uwagę, że żadna funkcja z tej jednostki tłumaczeniowej nigdy nie jest wywoływana. –

Odpowiedz

43

Użyj opcji linkera.

Biblioteki, które przychodzą po to w wierszu poleceń nie będą odrzucane symbole bez odniesień. Możesz wznowić normalne działanie łączenia, dodając po tych bibliotekach --no-whole-archive.

W przykładzie komenda będzie:

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

W ogóle, to będzie:

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

Czy ktoś wie, czy istnieje lepsza kontrola nad tym, jak korzystanie z widoczności DSO? Zastanawiam się nad tagowaniem kilku funkcji, które należy wymusić. Zobacz https://gc.gnu.org/wiki/Visibility – csl

+3

Użytkownik powinien jednak dodać na końcu '-Wl, -no-whole-archive'. Jak [man ld] (http://man7.org/linux/man-pages/man1/ld.1.html) mówi: * "Po drugie, nie zapomnij użyć' -Wl, -no-całe-archiwum 'po twojej liście archiwów, ponieważ gcc doda do twojego linku swoją własną listę archiwów i możesz nie chcieć, aby ta flaga również wpłynęła na te flagi." * – Sasha

+0

@csl, może http://stackoverflow.com/a/43894291/192373 odpowiada na twoje pytanie? –

4

Inne odpowiedzi podoba mi się lepiej, ale tutaj jest inne "rozwiązanie".

  1. Użyj polecenia ar, aby wyodrębnić wszystkie pliki .o z archiwum.

    cd mylib ; ar x /path/to/libmylib.a 
    
  2. Następnie dodać wszystkie te .o pliki do polecenia łącznikowej

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

Jeśli istnieje szczególna funkcja w statycznej biblioteki, który jest pozbawiony przez łącznik jak nieużywany, ale naprawdę tego potrzebuję (jednym z powszechnych przykładów jest funkcja JNI_OnLoad()), można zmusić linker do jej utrzymania (i oczywiście, cały kod, który jest wywoływany z tej funkcji). Dodaj -u JNI_OnLoad do polecenia połączenia.