2009-02-09 2 views
7

В настоящее время мы используем один инструмент командной строки для создания нашего продукта как для Windows, так и для Linux.Как объединить несколько файлов PDB?

Si far его работы красиво, что позволяет нам строить из источника и с более точной зависимостью, чем позволяла любая из наших предыдущих систем сборки. Это покупает нам большие возможности по наращиванию и параллельной сборке.

Для описания в скором времени процесс сборки, мы получаем обычное:

.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++ компилятор поддерживает его должным образом.

В последнее время возникла необходимость в создании нескольких статических библиотек. Из того, что мы собрались, чтобы процесс создания статической библиотеки является:

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

Сингл .pdb означает, что cl.exe должен быть выполнен только один раз для всех источников .cpp. Это единственное выполнение означает, что мы не можем распараллелить сборку для этой статической библиотеки. Это действительно неудачно.

Мы исследовали немного дальше и в соответствии с документацией (и доступные опции командной строки):

  • cl.exe не знает, как строить статические библиотеки
  • lib.exe не знает, как строить .pdb файлы

Кто-нибудь знает способ слияния нескольких файлов PDB? Неужели мы обречены на медленную сборку для статических библиотек? Как инструменты, подобные Incredibuild, работают над этой проблемой?

+0

Вы всегда можете поместить свой код на твердотельный накопитель. Сборка будет молниеносно. –

+0

Я нахожусь на твердотельном диске в своем учебнике. Это помогает, но привязка привязана к IO, компиляция связана с ЦП. –

ответ

5

Я еще долго не делал C++, но из этого article оказалось, что это трюк производительности, чтобы остановить воспроизведение символов для обычных заголовков.

Вы можете попробовать/Z7, чтобы вставлять информацию в каждый объект, а не создавать PDB, а затем связывать и воссоздавать его с помощью rebase, как в этом article.

+0

Не является ли отладочная информация от/Z7 отличной (и неполной) от того, что генерируется/Zi и/ZI? Согласно статье, связанной с кафе the egghead (http://support.microsoft.com/kb/258205), вы можете извлечь информацию об отладке из/Z7 в файл .dbg, а не файл .pdb. –

+1

обе эти ссылки теперь мертвы :( –

5

Не нужно объединять файлы PDB.

Скомпилируйте исходные файлы с помощью/Z7, чтобы избежать создания PDB во время шагов CL.EXE.

Используйте LIB.EXE для создания статических библиотек со встроенной отладочной информацией. Используйте LINK.EXE вместо CL.EXE для связи, используйте/PDB, чтобы указать, куда идет отладочная информация.

Если вы отлаживаете процесс с помощью EXE и одной или нескольких библиотек DLL, отправьте отладчику PDB для каждого изображения (EXE или DLL).

2

Файлы слияния PDB возможны, но могут выполняться только cl.exe и link.exe. Я не знаю никаких отдельных инструментов для объединения файлов PDB.

Вы можете использовать опцию/PDB для компоновщика (я проверил VC2005), чтобы указать альтернативное имя файла pdb.

Microsoft предлагает также включить файлы PDB (каждый obj имеет соответствующий файл PDB) вместе с .LIB-файлом.

Вы не можете архивировать файлы PDB внутри .LIB-файла, я пробовал его с VC2003, не удалось.

Скомпилировать с/Z7 можно избежать файлов PDB для .LIB, но объектные файлы большие, если link.exe не выводит информацию об отладке. Если у вас нет опции/debug для компоновщика, то ваш exe/dll не может быть отлажен.

Компилятор (cl.exe) всегда записывает в файл vcXX.pdb, если вы не используете параметр/Fd для указания другого имени. Даже когда вы используете cl.exe для создания исполняемого файла «напрямую», он будет создавать файл vc80.pdb, а затем файл link.exe будет вызывать имя файла pdb, аналогичное исполняемому.

кл/Zi test.c

cl.exe -> vc80.pdb link.exe чтения vc80.pdb (имя встраивается в test.obj файл) -> test.pdb

Каждый раз, когда cl/Zi/c скомпилирует файл, он попытается изменить существующий файл vcXX.pdb, а не переписать его.

Я получил вышеупомянутое соглашение путем игры с компилятором снова и снова, а затем захватил результат sixinternals и проанализировал его. Надеюсь, поможет.

0

Если вы не хотите, чтобы перераспределить статические библиотеки с отладочной информацией, вы на самом деле не нужно объединять любые PDB файлы (или использовать /Z7 для встраивания отладочной информации).

Как упоминалось @zhaorufei, при использовании /Zi каждый объектный файл содержит ссылку на его файл PDB, который затем использует компоновщик.

Просто используйте /Fd, чтобы дать каждый объект уникального 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 

Это также имеет то преимущество, что она работает вокруг вопросов параллельного доступа к общим файлам PDB упомянутого here, так что вы можете распараллелить компиляции как хотелось.

Затем свяжите/архивируйте объектные файлы, как обычно. VC++ уже включает различные виды информации в объектных файлах, чтобы передать их компоновщику, например, настройку ссылки на время выполнения и библиотеки зависимостей. Путь к файлу PDB не отличается. Создание статической библиотеки из объектов не удаляет ссылки:

> 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 

При соединении этой библиотеки в исполняемый или DLL, компоновщик все еще тянет в отладочную информацию из ссылочных PDB-файлы и добавляет его к окончательному PDB файла ,

Единственное предостережение, которое я вижу, заключается в том, что путь всегда является абсолютным, поэтому это может не сработать, если вы перемещаете файлы локально или на другую машину перед связыванием.

Смежные вопросы