Как объединить несколько файлов PDB? - PullRequest
8 голосов
/ 09 февраля 2009

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

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

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

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

Ответы [ 4 ]

5 голосов
/ 25 марта 2009

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

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

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

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

5 голосов
/ 19 марта 2009

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

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

2 голосов
/ 16 сентября 2010

Слияние файлов 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 read vc80.pdb (имя встроено в файл test.obj) -> test.pdb

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

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

1 голос
/ 05 марта 2017

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

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

...