2009-02-09 55 views
7

Actualmente estamos utilizando una sola herramienta de línea de comandos para construir nuestro producto tanto en Windows como en Linux.¿Cómo combino varios archivos PDB?

Si, funciona muy bien, lo que nos permite construir fuera de la fuente y con dependencias más finas que las permitidas por nuestro sistema de compilación anterior. Esto nos compra grandes capacidades incrementales y paralelas de construcción.

Para describir brevemente el proceso de construcción, tenemos la costumbre:

.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 

El msvc C/C++ soporta adecuadamente.

Recientemente surgió la necesidad de crear algunas bibliotecas estáticas. Por lo que hemos reunido, el proceso de construir una biblioteca estática es:

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

La única .pdb significa que cl.exe únicamente debería ser ejecutado una vez por todas las fuentes .cpp. Esta ejecución única significa que no podemos paralelizar la compilación para esta biblioteca estática. Esto es realmente desafortunado

Investigamos un poco más y de acuerdo a la documentación (y las opciones de línea de comandos disponibles):

  • cl.exe no sabe cómo construir bibliotecas estáticas
  • lib.exe no sabe cómo construir .pdb archivos

¿Alguien sabe una manera de combinar múltiples archivos PDB? ¿Estamos condenados a tener construcciones lentas para las bibliotecas estáticas? ¿Cómo trabajan herramientas como Incredibuild en torno a este problema?

+0

Siempre puede poner su código en una unidad de estado sólido. Las compilaciones serán muy rápidas. –

+0

Estoy en una unidad de estado sólido en mi libro de estilo. Ayuda, pero el enlace está vinculado a IO, la compilación está vinculada a la CPU. –

Respuesta

5

No he hecho C++ durante mucho tiempo, pero a partir de este article, parece que este es un truco de rendimiento para detener la recreación de símbolos para los encabezados comunes.

Puede intentar/Z7 para incrustar información en cada obj, y no crear un PDB y luego vincularlo y volver a crearlo con una rebase como en este article.

+0

¿La información de depuración de/Z7 no es diferente (e inferior) de la generada por/Zi y/ZI? De acuerdo con el artículo vinculado en el egghead cafe thead (http://support.microsoft.com/kb/258205) puede extraer la información de depuración de/Z7 en un archivo .dbg y no en un archivo .pdb. –

+1

ambos enlaces están ahora muertos :( –

5

No es necesario combinar los archivos de PDB.

Compile los archivos de origen con/Z7 para evitar la creación de un PDB durante los pasos CL.EXE.

Utilice LIB.EXE para crear libaries estáticos con información de depuración incorporada. Use LINK.EXE en lugar de CL.EXE para vincular, use/PDB para especificar a dónde va la información de depuración.

Si está depurando un proceso con un EXE y uno o más DLL, alimente su depurador un PDB para cada imagen (EXE o DLL).

2

Merge Los archivos PDB son posibles pero cl.exe y link.exe solo pueden hacerlo. NO conozco ninguna herramienta independiente para combinar archivos PDB.

Puede utilizar la opción/PDB para el enlazador (comprobé VC2005) para especificar el nombre de archivo pdb alternativo.

Microsoft sugiere incluir también archivos PDB (cada obj tiene un archivo PDB correspondiente) junto con el archivo .LIB.

No puede archivar archivos PDB dentro del archivo .LIB, lo he intentado con VC2003, ha fallado.

Compilar con/Z7 puede evitar archivos PDB para .LIB, pero los archivos de objeto son grandes, a menos que el link.exe elimine la información de depuración. Si no tiene una opción/debug para el enlazador, entonces su exe/dll no se puede depurar.

El compilador (cl.exe) siempre escribe en el archivo vcXX.pdb a menos que use la opción/Fd para especificar otro nombre. Incluso cuando usa cl.exe para producir un ejecutable "directamente", producirá un archivo vc80.pdb y luego el archivo link.exe producirá el nombre del archivo pdb igual que el ejecutable.

cl/Zi test.c

cl.exe -> vc80.pdb link.exe leer vc80.pdb (el nombre está incrustado en test.obj archivo) -> test.pdb

Cada vez que cl/Zi/c compila un archivo, intentará modificar el archivo vcXX.pdb existente en lugar de sobrescribirlo.

Obtuve la conspiración anterior jugando con el compilador una y otra vez, luego capturo el resultado de procexp de sysinternals y lo analizo. Espero eso ayude.

0

A menos que desee redistribuir las bibliotecas estáticas con información de depuración, que en realidad no necesita fusionar los archivos PDB (o utilizar /Z7 para incrustar la información de depuración).

Como se menciona en @zhaorufei, al usar /Zi, cada archivo de objeto contiene una referencia a su archivo PDB, que el vinculador luego usa.

Sólo tiene que utilizar /Fd para dar a cada objeto un archivo PDB único:

> 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 

Esto también tiene la ventaja de que funciona en torno a los temas de acceso simultáneo a los archivos PDB compartidos mencionado here, por lo que puede paralelizar la compilación paso como tu quisiste

A continuación, enlace/archive los archivos del objeto como de costumbre. VC++ ya incorpora varios tipos de información en los archivos de objetos para pasarlos al enlazador, como la configuración del enlace de tiempo de ejecución y las bibliotecas de dependencias: la ruta del archivo PDB no es diferente. Creación de una biblioteca estática de los objetos no quita las referencias:

> 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 

Al vincular esta biblioteca a un archivo ejecutable o DLL, el enlazador todavía tira en la información de depuración de los PDB referenciados y lo añade al archivo PDB definitiva .

La única advertencia que puedo ver es que la ruta es siempre absoluta, por lo que puede no funcionar si mueves los archivos localmente o a otra máquina antes de vincular.