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

StackOverflow https://stackoverflow.com/questions/645747

Вопрос

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

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

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

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

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

Это было полезно?

Решение

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

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

  

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

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

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

  

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

Другие советы

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

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

Шаг за шагом:

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

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

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

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

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

     pch включить включать

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

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

    Самаурса ответил на меня.

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

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

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

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top