2009-02-09 7 views
7

Attualmente stiamo utilizzando un unico strumento da riga di comando per creare il nostro prodotto su Windows e Linux.Come si uniscono più file PDB?

Si va benissimo, permettendoci di costruire fuori dalla sorgente e con dipendenze più fini di quelle consentite da qualsiasi nostro precedente sistema di costruzione. Questo ci porta grandi capacità di build incrementali e parallele.

Per descrivere brevemente il processo di compilazione, si ottiene la solita:

.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 

Il msvc C/C++ supporta adeguatamente.

Recentemente è emersa la necessità di creare alcune librerie statiche. Da quello che abbiamo raccolto, il processo per costruire una libreria statica è:

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

Il singolo PDB significa che cl.exe deve essere eseguito solo una volta per tutte le fonti cpp. Questa singola esecuzione significa che non possiamo parallelizzare la build per questa libreria statica. Questo è davvero sfortunato.

Abbiamo studiato un po 'oltre e secondo la documentazione (e le opzioni della riga di comando disponibili):

  • cl.exe non sa come costruire librerie statiche
  • lib.exe non sa come costruire PDB file

Qualcuno conosce un modo per unire più file PDB? Siamo destinati ad avere build lente per le librerie statiche? Come fanno gli strumenti come Incredibuild a risolvere questo problema?

+0

È sempre possibile inserire il codice su un'unità a stato solido. Le costruzioni saranno velocissime. –

+0

Sono su un disco a stato solido sul mio stylebook. Aiuta, ma il collegamento è legato all'IO, la compilazione è legata alla CPU. –

risposta

5

Non ho fatto C++ per molto tempo ma da questo article, sembra che questo è un trucco di prestazioni per fermare la ricreazione di simboli per intestazioni comuni.

Si potrebbe provare/Z7 per incorporare informazioni in ogni oggetto, non creare un PDB e quindi collegarlo e ricrearlo con un rebase come in questo article.

+0

Le informazioni di debug di/Z7 sono diverse (e inferiori) rispetto a quanto generato da/Zi e/ZI? Secondo l'articolo collegato a egghead cafe thead (http://support.microsoft.com/kb/258205) è possibile estrarre le informazioni di debug da/Z7 in un file .dbg e non in un file .pdb. –

+1

entrambi questi link sono morti :( –

5

Non è necessario unire file PDB.

Compilare i file di origine con/Z7 per evitare di creare un PDB durante i passi di CL.EXE.

Utilizzare LIB.EXE per creare librerie statiche con informazioni di debug incorporate. Utilizzare LINK.EXE anziché CL.EXE per il collegamento, utilizzare/PDB per specificare dove vanno le informazioni di debug.

Se si esegue il debug di un processo con un EXE e una o più DLL, alimentare il debugger un PDB per ogni immagine (EXE o DLL).

2

Unisci file PDB sono possibili ma possono essere eseguiti solo da cl.exe e link.exe. NON conosco alcuno strumento stand-alone per unire file PDB.

È possibile utilizzare l'opzione/PDB per il linker (ho controllato VC2005) per specificare il nome del file pdb alternativo.

Microsoft consiglia di includere anche i file PDB (ogni oggetto ha un file PDB corrispondente) insieme al file .LIB.

Non è possibile archiviare i file PDB all'interno del file .LIB, l'ho provato con VC2003, non è riuscito.

Compilare con/Z7 può evitare file PDB per .LIB, ma i file oggetto sono grandi, a meno che il link.exe non elimini le informazioni di debug. Se non hai un'opzione/debug per il linker, allora il tuo exe/dll non può essere debugato.

Il compilatore (cl.exe) scrive sempre nel file vcXX.pdb a meno che non si usi l'opzione/Fd per specificare un altro nome. Anche se si utilizza cl.exe per produrre un file eseguibile "direttamente", verrà generato un file vc80.pdb e quindi il link.exe produrrà il nome del file pdb come l'eseguibile.

cl/Zi test.c

cl.exe -> vc80.pdb link.exe leggere vc80.pdb (il nome è incorporato nel test.obj file) -> test.pdb

Ogni volta che cl/Zi/c compila un file, proverà a modificare il file vcXX.pdb esistente invece di sovrascriverlo.

Ho ottenuto la conslusione di cui sopra giocando ancora e ancora con il compilatore, quindi acquisisco il risultato procexp di sysinternals e lo analizzo. Spero che sia d'aiuto.

0

A meno che non si desidera ridistribuire le librerie statiche con informazioni di debug, in realtà non hanno bisogno di unire tutti i file PDB (o utilizzare /Z7 per incorporare le informazioni di debug).

Come menzionato @zhaorufei, quando si utilizza /Zi, ogni file oggetto contiene un riferimento al proprio file PDB, che viene quindi utilizzato dal linker.

Basta usare /Fd per dare ad ogni oggetto un file PDB unico:

> 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 

Questo ha anche il vantaggio che funziona intorno alle questioni di accesso simultaneo ai file PDB condivisi menzionato here, in modo da poter parallelizzare la compilazione passo come volevi.

Quindi collegare/archiviare i file oggetto come al solito. VC++ incorpora già vari tipi di informazioni nei file oggetto per passarli al linker, ad esempio l'impostazione del collegamento di runtime e le librerie di dipendenze: il percorso del file PDB non è diverso. Creazione di una libreria statica dagli oggetti non rimuove i riferimenti:

> 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 

Quando si collega questa libreria per un file eseguibile o DLL, il linker tira ancora in informazioni di debug dalle PDB di riferimento e lo aggiunge al file PDB finale .

L'unica avvertenza che posso vedere è che il percorso è sempre assoluto, quindi potrebbe non funzionare se si spostano i file in locale o su un'altra macchina prima del collegamento.