Совместное использование предварительно скомпилированных заголовков между проектами в Visual Studio - PullRequest
40 голосов
/ 14 марта 2009

У меня есть решение для многих проектов Visual C ++, все из которых используют PCH, но в некоторых из них включены определенные переключатели компилятора для конкретных нужд проекта.

Большинство этих проектов используют один и тот же набор заголовков в соответствующем stdafx.h (STL, boost и т. Д.). Мне интересно, возможно ли разделить PCH между проектами, чтобы вместо компиляции каждого PCH для проекта у меня мог быть один общий PCH, который большинство проектов в решении могли бы просто использовать.

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

Кто-нибудь пробовал это? Это работает?

Смежный вопрос: должен ли такой осколочный PCH быть чрезмерно инклюзивным или это повредит общему времени сборки? Например, общий PCH может включать много широко используемых заголовков STL, но для некоторых проектов могут потребоваться только <string> и <vector>. Нужно ли возвращать время, сэкономленное с помощью общего PCH, на более позднем этапе процесса сборки, когда оптимизатору придется отбрасывать все неиспользуемые материалы, перетаскиваемые в проект PCH?

Ответы [ 5 ]

23 голосов
/ 13 ноября 2010

Да, это возможно, и я могу заверить вас, экономия времени значительна. Когда вы компилируете свой PCH, вы должны скопировать файлы .pdb и .idb из проекта, который создает файл PCH. В моем случае у меня есть простой двухфайловый проект, который создает файл PCH. Заголовок будет вашим заголовком PCH, а источнику будет предложено создать PCH в настройках проекта - это похоже на то, что вы обычно делаете в любом проекте. Как вы упомянули, вы должны иметь одинаковые параметры компиляции для каждой конфигурации, в противном случае возникнет несоответствие, и компилятор будет жаловаться.

Копирование вышеупомянутых файлов каждый раз, когда происходит перестроение или каждый раз, когда перекомпилируется PCH, будет проблемой, поэтому мы автоматизируем это. Чтобы автоматизировать копирование, выполните событие перед сборкой, в котором вышеупомянутые файлы будут скопированы в соответствующий каталог. Например, если вы компилируете сборки Debug и Release своего PCH, скопируйте файлы из Debug вашего проекта PCH в Debug вашего зависимого проекта. Таким образом, команда копирования будет выглядеть так

copy PchPath \ Debug * .pdb Debug \ / -Y

Обратите внимание на /-Y в конце. После первой сборки каждая последующая сборка постепенно компилируется, поэтому при повторной замене файлов Visual Studio будет жаловаться на поврежденные символы. Если они повреждены, вы всегда можете выполнить перестроение, при котором файлы будут скопированы снова (на этот раз они не будут пропущены, так как они больше не существуют - программа очистки удалит файлы).

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

РЕДАКТИРОВАТЬ: Вместе с несколькими другими людьми, я проверил это под VS2010 и VS2012, и, похоже, он работает правильно.

12 голосов
/ 13 марта 2017

Хотя это старый вопрос, я хочу дать новый ответ, который работает в Visual Studio 2017 и не требует копирования. Единственный недостаток: редактировать и продолжать больше не работает.

По сути, вы должны создать новый проект для предварительно скомпилированного заголовка, и все остальные проекты зависят от него. Вот что я сделал:

Шаг за шагом:

  1. Создайте новый проект в вашем решении, который включает в себя заголовок (далее именуемый pch.h) и однострочный файл cpp, который включает pch.h. Проект должен создать статическую библиотеку. Настройте новый проект для создания предварительно скомпилированного заголовка. Выходной файл должен быть доступен всем проектам. для меня это относительно IntDir, но для настроек по умолчанию это может быть относительно $ (SolutionDir). В проекте pch должны быть определены только все остальные проекты.

    pch project settings

  2. Все другие проекты зависят от этого нового проекта. В противном случае порядок сборки может быть неправильным.

    project references

  3. Настройте все другие проекты для использования файла pch.h. Посмотрите, как параметры выходного файла такие же, как в проекте pch. Дополнительные каталоги include также должны указывать на каталог pch.h. При желании вы можете принудительно включить файл pch в каждый файл cpp (или включить его вручную в первую строку каждого файла cpp).

    pch include include

    1. Настройка всех проектов (включая проект pch) на использование одного и того же файла символов компилятора (файл символов компоновщика не затрагивается). Опять же, в моем примере это OutDir, но в вашем решении это может отличаться. Он должен указывать на тот же файл на диске. Формат отладочной информации должен быть установлен на C7 (см. Скриншот выше), иначе Visual Studio не сможет компилировать проекты параллельно. pdb

Надеюсь, я ничего не забыл. Для моего решения (130k loc, 160 проектов) это привело к времени компиляции ~ 2: 30 минут вместо ~ 3: 30 минут.

5 голосов
/ 16 декабря 2010

Ответ Самурсы работал на меня.

Я также видел эту ссылку , которая работает (ищите ответ Реджинальда внизу).

Этот использует copy, в то время как Реджинальд использует xcopy (я предпочитаю xcopy). В любом случае, спасибо - это значительно ускорило мои сборки.

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

Кажется, что это невозможно, потому что каждый исходный файл должен быть скомпилирован с той же PDB, с которой был скомпилирован PCH. Черт возьми.

3 голосов
/ 14 марта 2009

Это звучит как случай "убывающей отдачи" для меня. Предположим, что включение общих заголовков напрямую тратит 1 секунду на файл .cpp, и каждая цель (DLL / EXE) имеет 10 файлов .cpp. Используя .pch на цель, вы экономите 10 секунд на цель. Если у всего вашего проекта 10 целей, вы экономите 1,5 минуты на всей сборке, и это хорошо.

Но, сократив его до одного .pch для всего проекта, вы сэкономите еще 9 секунд. Стоит ли оно того? Дополнительные усилия (которые могут быть гораздо более сложными в настройке, будучи нестандартной конфигурацией, не поддерживаемой мастерами VS) дают только 10-ю экономию.

...