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

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

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

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

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

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

5 ответов

Решение

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

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

скопировать PchPath\Debug*.pdb Debug\ /-Y

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

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

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

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

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

Шаг за шагом:

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

    настройки проекта pch

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

    ссылки на проект

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

    пч включают включают

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

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

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

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

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

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

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

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

В 2012 году вы можете использовать PDB и просто собрать pch из проекта библиотеки, который строит только pch и основной проект, который зависит от pch lib в одном каталоге (без копирования), к сожалению, это не работает с 2013+ за исключением долгой работы.

Другие вопросы по тегам