Подтвердить что ты не робот

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

EDIT: Наряду с несколькими другими людьми, я тестировал это под VS2010 и VS2012, и он работает нормально.

Ответ 2

Хотя это старый вопрос, я хочу дать новый ответ, который работает в Visual Studio 2017 и не требует какого-либо копирования. Только недостаток: Edit и continue больше не работают.

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

Шаг за шагом:

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

    параметры проекта pch

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

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

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

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

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

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

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

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

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