2009-02-09 17 views
7

Obecnie używamy jednego narzędzia wiersza poleceń, aby zbudować nasz produkt zarówno w systemie Windows, jak i Linux.Jak scalić wiele plików PDB?

Swoim działaniem ładnie się spisuje, co pozwala nam budować z zasobów źródłowych i subtelniejszymi niż to, co pozwalał nasz poprzedni system kompilacji. To daje nam świetne, równoległe możliwości budowania.

Aby opisać krótko proces kompilacji otrzymujemy zwykle:

.cpp -- cl.exe --> .obj and .pdb 
multiple .obj and .pdb -- cl.exe --> single .dll .lib .pdb 
multiple .obj and .pdb -- cl.exe --> single .exe .pdb 

msvc C/C++ kompilator wspiera go odpowiednio.

Ostatnio pojawiła się potrzeba zbudowania kilku bibliotek statycznych. Z tego, co zebraliśmy, proces budowania statycznych biblioteki jest:

multiple .cpp -- cl.exe --> multiple .obj and a single .pdb 
multiple .obj -- lib.exe --> a single .lib 

Singiel .pdb oznacza, że ​​cl.exe powinny być wykonywane tylko raz dla wszystkich źródeł .cpp. Ta pojedyncza operacja oznacza, że ​​nie możemy zrównoważyć kompilacji tej statycznej biblioteki. To naprawdę niefortunne.

Badaliśmy kawałek dalej i zgodnie z dokumentacją (i dostępnych opcji wiersza poleceń):

  • cl.exe nie wie, jak zbudować statycznych bibliotek
  • lib.exe nie wie, jak zbudować .pdb pliki

Czy ktoś zna sposób scalania wielu plików PDB? Czy jesteśmy skazani na powolne kompilacje dla bibliotek statycznych? W jaki sposób narzędzia takie jak Incredibuild radzą sobie z tym problemem?

+0

Zawsze można umieścić kod na dysku SSD. Budowy będą błyskawiczne. –

+0

Mam dysk SSD w moim stylubook. Pomaga, ale łączenie jest związane z IO, kompilacja jest związana z procesorem. –

Odpowiedz

5

Nie robiłem C++ przez długi czas, ale z tego article, wydaje się, że jest to trik wydajności, aby zatrzymać odtwarzanie symboli dla wspólnych nagłówków.

Możesz spróbować/Z7 osadzić informacje w każdym obiekcie, a nie tworzyć PDB, a następnie łączyć i odtwarzać je z bazą danych, jak w tym article.

+0

Czy dane debugowania z/Z7 nie są różne (i gorsze) od tego, co jest generowane przez/Zi i/ZI? Zgodnie z artykułem połączonym z witryną jajową thead (http://support.microsoft.com/kb/258205) można wyodrębnić informacje dotyczące debugowania z/Z7 do pliku .dbg, a nie do pliku .pdb. –

+1

oba te linki są już martwe :( –

5

Nie trzeba scalać plików PDB.

Skompiluj pliki źródłowe za pomocą/Z7, aby uniknąć tworzenia PDB podczas kroków CL.EXE.

Użyj pliku LIB.EXE, aby utworzyć statyczne biblioteki z osadzonymi informacjami diagnostycznymi. Użyj LINK.EXE zamiast CL.EXE, aby połączyć, użyj/PDB, aby określić, gdzie znajdują się informacje dotyczące debugowania.

Jeśli debugujesz proces z EXE i jedną lub więcej bibliotek DLL, podaj swój debugger PDB dla każdego obrazu (EXE lub DLL).

2

Scalanie plików PDB jest możliwe, ale można to zrobić tylko za pomocą cl.exe i link.exe. NIE znam żadnych standardowych narzędzi do scalania plików PDB.

Możesz użyć opcji/PDB do linkera (sprawdziłem VC2005), aby określić alternatywną nazwę pliku pdb.

Firma Microsoft sugeruje również dołączenie plików PDB (każdy obiekt ma odpowiedni plik PDB) wraz z plikiem .LIB.

Nie można archiwizować plików PDB w pliku .LIB, próbowałem go z VC2003, nie powiodło się.

Kompilacja z/Z7 pozwala uniknąć plików PDB dla .LIB, ale pliki obiektów są duże, chyba że link.exe usuwa informacje debugowania. Jeśli nie masz opcji/debug do linkera, to nie można debugować pliku exe/dll.

Kompilator (cl.exe) zawsze zapisuje do pliku vcXX.pdb, chyba że użyje się opcji/Fd do określenia innej nazwy. Nawet jeśli użyjesz cl.exe do utworzenia pliku wykonywalnego "bezpośrednio", utworzy on plik vc80.pdb, a następnie plik link.exe utworzy nazwę pliku pdb taką samą, jak plik wykonywalny.

cl/Zi test.c

cl.exe -> vc80.pdb link.exe czytać vc80.pdb (nazwa jest osadzony w test.obj pliku) -> test.pdb

Za każdym razem, gdy cl/Zi/c skompiluje plik, spróbuje zmodyfikować istniejący plik vcXX.pdb zamiast go nadpisać.

Mam powyższą konsolę, odtwarzając raz po raz kompilator, a następnie przechwytuję wynik proceksp sysinternali i analizuję go. Mam nadzieję, że to pomoże.

0

ile chcesz redystrybucji statycznych bibliotek z informacji debugowania, nie faktycznie trzeba połączyć wszystkie pliki PDB (lub użyć /Z7 aby osadzić informacje debugowania).

Jak wspomniał @zhaorufei, podczas korzystania z /Zi, każdy plik obiektowy zawiera odniesienie do jego pliku PDB, który następnie wykorzystuje linker.

Wystarczy użyć /Fd dać każdy obiekt unikalny plik PDB:

> cl -c foo.cpp -Fo:target/foo.obj -Fd:target/foo.pdb -Zi 
> cl -c bar.cpp -Fo:target/bar.obj -Fd:target/bar.pdb -Zi 

> strings target/foo.obj | grep pdb 
D:\Dev\sample\target\foo.pdb 
> strings target/bar.obj | grep pdb 
D:\Dev\sample\target\bar.pdb 

Ma to również tę zaletę, że nie radzi sobie z tym kwestii jednoczesnego dostępu do udostępnionych plików PDB wspomniany here, więc można parallelize kompilacji krok jak chciałeś.

Następnie należy połączyć/zarchiwizować pliki obiektów w zwykły sposób. VC++ już osadza różnego rodzaju informacje w plikach obiektowych, aby przekazać je do łącznika, takie jak ustawienia łącza uruchomieniowego i biblioteki zależności - ścieżka pliku PDB nie jest inna. Tworzenie statycznej biblioteki z obiektów nie usuwa odniesienia:

> lib -out:target/all.lib target/foo.obj target/bar.obj 
> strings target/all.lib | grep pdb 
D:\Dev\sample\target\bar.pdb 
D:\Dev\sample\target\foo.pdb 

Kiedy powiązanie tej biblioteki do pliku wykonywalnego lub DLL, łącznik nadal ciągnie w informacji debugowania z przywoływanych PDBs i dodaje go do ostatecznego pliku PDB .

Jedyne zastrzeżenie, jakie widzę, to fakt, że ścieżka jest zawsze absolutna, więc może nie działać, jeśli pliki zostaną przeniesione lokalnie lub na inną maszynę przed połączeniem.

Powiązane problemy