Как объединить несколько файлов PDB?

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

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

Если коротко описать процесс сборки, то получаем обычное:

.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, решают эту проблему?


person bltxd    schedule 09.02.2009    source источник
comment
Вы всегда можете поместить свой код на твердотельный накопитель. Сборки будут молниеносными.   -  person Jonathan Parker    schedule 26.03.2009
comment
Я на твердотельном накопителе в своей книге стилей. Это помогает, но связывание связано с вводом-выводом, а компиляция связана с процессором.   -  person Justin Dearing    schedule 04.07.2010


Ответы (4)


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

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

person Preet Sangha    schedule 19.03.2009
comment
Разве отладочная информация из /Z7 не отличается (и хуже) от той, что генерируется /Zi и /ZI? Согласно статье, на которую ссылается реклама в кафе-яйцеголовом (support.microsoft.com/kb/258205) вы можете извлечь отладочную информацию из /Z7 в файл .dbg, а не в файл .pdb. - person Justin Dearing; 04.07.2010
comment
обе эти ссылки уже мертвы :( - person Amish Programmer; 20.12.2012

Нет необходимости объединять файлы PDB.

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

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

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

person janm    schedule 25.03.2009

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

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

Microsoft предлагает также включить файлы PDB (каждый объект имеет соответствующий файл 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, такое же, как у исполняемого файла.

cl/Zi test.c

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

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

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

person zhaorufei    schedule 16.09.2010

Если вы не хотите распространять статические библиотеки с отладочной информацией, вам не нужно объединять какие-либо файлы 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, упомянутые здесь, чтобы вы могли распараллелить этап компиляции, как вам хотелось.

Затем свяжите/заархивируйте объектные файлы, как обычно. 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-файл.

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

person melak47    schedule 05.03.2017