2011-02-07 16 views
16

Mam aplikacji C++, który odziedziczyłem, który składa się z:Czy mogę uzyskać raport WSZYSTKICH bibliotek połączonych podczas budowania mojego pliku wykonywalnego C++ (gcc)? (W tym powiązane statycznie)

  • Moim głównym aplikacji
  • kilku bibliotek specyficznych dla aplikacji (libapp1, libapp2, etc ...)
  • Kilka bibliotek "trzecich" (większość "trzecia strona to po prostu inne zespoły w firmie") połączonych zarówno z głównej aplikacji, z bibliotek libappX specyficznych dla aplikacji, jak iz innych bibliotek trzeciej części - np. libext1, libext2, etc ...

Innymi słowy, mój kod wygląda następująco:

// main.C 
#include <app1/a1l1.H> 
#include <app2/a2l1.H> 
#include <ext1/e1l1.H> 

// app1/a1l1.H 
#include <app1/a1l2.H> 
#include <ext2/e2l1.H> 

// app2/a2l1.H 
#include <ext2/e2l2.H> 

// ext1/e1l1.H 
#include <ext3/e3l1.H> 

// ext3/e3l1.H 
#include <ext4/e4l1.H> 

pytania:

1) Jak mogę sprawdzić, które zostały połączone biblioteki do końcowego pliku wykonywalnego? musi ona obejmować statycznie połączone te

Innymi słowy, chcę odpowiedzieć na „App1, App2, EXT1, ext2, ext3, ext4”

Idealnie, odpowiedź byłaby dostępna od samego pliku wykonywalnego (Mam wbudowaną wersję debugowania, na wypadek gdyby było to bardziej możliwe). Jeśli to niemożliwe, chciałbym wiedzieć, czy istnieje proste narzędzie do analizy kodu (iedeally coś w samym gcc), aby zapewnić tę analizę.

Należy pamiętać, że pliki obiektów dla bibliotek zewnętrznych są już zbudowane, więc patrząc na dzienniki kompilacji, aby zobaczyć, co było połączone, obawiam się, że "ext4" nie pojawi się w dzienniku, ponieważ nie będziemy buduj bibliotekę "ext3", która jest już gotowa.

UWAGA: uruchomienie "nmake" z DEPS ustawionym na yes, aby odbudować wszystkie, NIE jest opcją. Ale mam dostęp do pełnego kodu źródłowego dla bibliotek zewnętrznych.

2) Nieco oddzielne i mniej ważne pytanie, w jaki sposób mogę powiedzieć listę wszystkich w plikach używanych w całym drzewie źródłowym, które buduję. Znowu, najlepiej już skompilowany plik wykonywalny frm, który mam wersję debugowania.

=================

UPDATE: Właśnie w celu wyjaśnienia, nasze biblioteki są połączone statycznie, więc ldd (Lista Synamic Zależności) nie działa.

Odpowiedź też może dotyczyć systemu Solaris lub Linux - nie ma znaczenia.

Próbowałem za pomocą nm ale nie listy bibliotek

+0

Jakiej platformy używasz? – Tom

+0

@Tom - w systemie Solaris lub Linux. Nie obchodzi mnie, czy odpowiedź jest ogólna dla obu, czy tylko na jednej. – DVK

+0

Proponuję ldd następnie na pierwsze pytanie – Tom

Odpowiedz

21

Miałem podobny problem i znalazłem rozwiązanie: add -Wl, - verbose option when linking. Będzie łącznik przełączyć do trybu potwierdzania:

gcc -o test main.o -ltest -L. -Wl,--verbose 

Oto przykład wyjście:

GNU ld (GNU Binutils) 2.23.52.20130604 
    Supported emulations: 
    i386pep 
    i386pe 
using internal linker script: 
================================================== 
/* Default linker script, for normal executables */ 
[many lines here] 
================================================== 
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o succeeded 
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o 
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o succeeded 
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o 
attempt to open main.o succeeded 
main.o 
attempt to open ./libtest.dll.a failed 
attempt to open ./test.dll.a failed 
attempt to open ./libtest.a succeeded 
(./libtest.a)test.o 
[more lines here] 
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o succeeded 
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o 

Aktualizacja: Można również użyć -Wl, - możliwość śledzenia zamiast -Wl - gadatliwy . Poda także listę bibliotek, ale jest mniej obszerna.

Aktualizacja 2: -Wl, - trace nie wyświetla bibliotek zawartych pośrednio. Przykład: łączysz się z libA, a libA jest połączone z libB. Jeśli chcesz zobaczyć, że libB jest również potrzebny, musisz użyć -Wl, - verbose.

+1

Jako notatka dla obserwujących, pliki ".o" 'ld' zawierają listę bibliotek (tj. Te wymienione poniżej) mówi: "próba otwarcia biblioteki libXX powiodła się") nie będzie "wszystkimi" plikami .o w bibliotece, tylko tymi, których potrzebuje do zaspokojenia zależności w tym punkcie. Reszta jest w zasadzie odrzucona, mimo że znajduje się w pliku .a. ref: http://stackoverflow.com/q/14091669/32453 – rogerdpack

9

Dla bezpośrednich zależności;

ldd <app> 

Zależności pośrednie/wszystkie;

ldd -r <app> 
+0

Przepraszamy za nie wyjaśnienie tego wcześniej, biblioteki są statycznie połączone. 'ldd' nie wymienia tych. – DVK

+0

Znalazłem odpowiedź, której szukałem, dzięki Twojej odpowiedzi, dzięki! – jredd

1

Spróbuj użyć ldd + nazwy pliku, to wyświetli listę bibliotek.

+1

Niestety, nie wyjaśniając tego wcześniej, biblioteki są statycznie połączone. 'ldd' nie wymienia tych. – DVK

4

Z tego co wiem, niewiele informacji o bibliotekach statycznych jest zachowanych podczas łączenia (ponieważ linker widzi tę bibliotekę jako zbiór obiektów * .o).

Jeśli znajdziesz polecenie make, które łączy ostateczny plik wykonywalny i dodaje flagę -v, g++ pokaże dokładnie, w jaki sposób wywołuje polecenie ld. Powinno to obejmować wszystkie niezbędne biblioteki statyczne, w tym biblioteki używane przez inne biblioteki, w przeciwnym razie krok łącza nie powiedzie się. Ale może również zawierać dodatkowe biblioteki, które nie są faktycznie używane.

Inną prawdopodobnie użyteczną rzeczą jest to, że przynajmniej w systemie Linux obiekty i pliki wykonywalne zwykle przechowują nazwy plików z kodem źródłowym, z których zostały utworzone. (Tylko nazwa pliku, brak ścieżki). Spróbuj

objdump -t executable | grep '*ABS*' 
+0

Wydaje się, że objdump tworzy wyjście bardzo podobne do 'nm' i nie tworzy naprawdę list bibliotek. Czy mogę przekazać "-v" za pomocą przełącznika wiersza poleceń do nmake? Thx – DVK

+0

@DVK: AT & T nmake? Microsoft nmake? W każdym razie prawdopodobnie nie.Chcesz znaleźć ostatnie polecenie 'g ++', które zrobił lub wywołał proces make, a następnie dodaj do tego -v. – aschepler

+0

gotcha. Domyślam się, że robi to już domyślnie, ponieważ myślę, że widzę listę wszystkich plików .a w wierszu poleceń g ++ – DVK

0

Najpierw odpowiem na twoje drugie pytanie. Możesz po prostu użyć flagi -H lub -M, aby zobaczyć wszystkie nagłówki (w tym systemowe) przetwarzane w kompilacji. gcc -H main.c powinien załatwić sprawę. Co widząc nagłówki zawarte są rzeczywiście dostać się na dobrej drodze do znalezienia które biblioteki statyczne były powiązane w.

Można użyć objdump na swojej końcowej przedmiotu (lub readelf na swojej ostatecznej binarnego), aby uzyskać nazwy wszystkich działa tam. Musiałbyś wtedy znaleźć biblioteki, z których funkcje zostały wciągnięte, ale to trochę uciążliwe. Zdecydowanie musiałbyś stworzyć scenariusz, aby zminimalizować ból.

Ktoś inny wymieniony przy użyciu gcc <stuff> -Wl,-verbose, który po prostu przekazuje flagę -verbose. To doskonały sposób na uzyskanie listy bibliotek współużytkowanych (plików .so), ale powiedziałeś, że twoje są statyczne, więc to nie jest sposób, aby przejść w tym przypadku.

Powodzenia!

Powiązane problemy