2012-12-21 9 views
10

Buduję program z autoconf, automake i libtool. Moja praca wymaga statycznego łączenia (większości) bibliotek. Nie było to w przeszłości problemem, ponieważ mogłem statycznie powiązać wszystko z -all-static. Teraz jest to problem, ponieważ muszę korzystać z biblioteki, która jest tylko dynamiczna; zostało nam dane przez osobę trzecią, a my nie mamy źródła.W jaki sposób użytkownik automatyczny może określić kombinację łączenia statycznego i dynamicznego?

Oczywiście, -all-static powoduje teraz awarię kompilacji. Czy jest możliwe aby powiedzieć libtool statycznie połączyć wszystko, z wyjątkiem tej jednej biblioteki? Czy jest możliwe, aby libtool zawierał dowolne połączenie statycznego i dynamicznego łączenia, czy to wszystko czy nic?

Do tej pory próbowałem stworzyć bibliotekę wygody z LDFLAGS = -static, która zależy od bibliotek, które chcę statycznie połączyć. Ale libtool nie łączy statycznych bibliotek, tak jak bym sobie tego życzył. Program w zależności od biblioteki wygody wciąż dynamicznie łączy wszystko.

Próbowałem również --disable-shared, ale to nie miało wpływu na kompilację.


Te pytania są podobne, ale tak naprawdę nie jest odpowiedź na moje pytanie:

Force linking a static library into a shared one with Libtool

Is it possible to link some — but not all — libraries statically with libtool?

(nie chcę usunąć biblioteki współdzielone z mojego systemu, a określanie pełnej ścieżki dla wszystkiego nie jest lepsze niż łączenie ręczne, ale może to jedyny sposób.)

Odpowiedz

10

Zrobiłeś ot określ system operacyjny, ale załóżmy, że jest to stosunkowo nowy Unix/Linux/OSX. Jeśli nie, zignoruj ​​następujące ostrzeżenie.

Zanim odpowiem, powinieneś wiedzieć, że mieszanie kodu statycznego i współdzielonego w większości systemów opartych na ELF (Unix/Linux) jest problematyczne. Jednym z powodów jest to, że może doprowadzić do zsynchronizowania kodu, jeśli zapomnisz połączyć zaktualizowaną zależność. Kolejny wynika z charakteru kodu statycznego w stosunku do PIC. Właśnie dlatego libtool próbuje go zniechęcić.

Mając na uwadze powyższe, w Makefile.am (zakładając swój ostateczny program jest foo i wspólna biblioteka jest):

. 
    . 
    . 
    foo_SOURCES = foo.c abc.c def.c hij.c 
    foo_LDFLAGS = -all-static -Wl,-Bdynamic,-L/path/to,-lshared,-Bstatic 
    foo_LDADD = -L../path/to -lbar -lbaz 

Co ważne jest to, że libtool pozwala na zwarcia i kontrole Flaga GNU gcc -static (używana przez libtool) przekazując argumenty -Wl, bezpośrednio do linkera (GNU ld). Aby wstawić spacje między argumentami, używany jest separator przecinka ,.

Zarówno -Bstatic, jak i -Bdynamic są udokumentowane w pliku info pages GNU ld oraz na ekranie pomocy. Ponownie, ponieważ nie wspomniałeś o używanym pakiecie os lub kompilatorze, zakładam GNU gcc i GNU ld na Linuksie. Możesz sprawdzić, korzystając z ld --help, aby przekonać się sam. Jeśli z jakiegoś powodu nie jest to GNU ld, to musisz znaleźć odpowiednie flagi do -Bstatic i -Bdynamic, zastępując w razie potrzeby.

+1

Działa to, ale z powodu braku pewnej elastyczności.Nie potrzebuję dynamicznej kompilacji, ale gdybym to zrobił, musiałbym edytować plik 'Makefile.am', prawda? Powoduje to również problemy z makrami, takimi jak 'AC_CHECK_LIB' (które po prostu dodaje' -l' do 'LIBS'), ale myślę, że tego można się spodziewać. – tprk77

+2

Podałem najprostsze możliwe podejście. Jednak, na coś wyszukanego, możesz przeciągnąć flagi do 'configure.ac'. Tam możesz dodać 'DYNLIBS =" - Wl, -Bdynamic, -L/path/to, -lshared, -Bstatic "' z wywołaniem 'AC_SUBST ([DYNLIBS])'. Następnie wystarczy wywołać '$ (DYNLIBS)' w pliku 'Makefile.am'. To da ci większą kontrolę, ale pamiętaj, że 'AC_CHECK_LIBS' nie sprawdza bibliotek statycznych vs. dynamicznych. Czy to jest to, czego chcesz, czy jest coś jeszcze, co uczyniłoby to bardziej elastycznym? – NickW

+0

Tak, myślę, że to zadziała, dzięki! – tprk77

Powiązane problemy