Spec-Zone.ru › GCC 13

3.22 Использование предварительно скомпилированных заголовков

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

Для создания предварительно скомпилированного заголовочного файла просто скомпилируйте его, как любой другой файл, при необходимости используя опцию -x, чтобы заставить драйвер обрабатывать его как заголовочный файл C или C++ . Возможно, вам потребуется использовать инструмент, такой как make, чтобы поддерживать актуальность предварительно скомпилированного заголовка при изменении заголовков, которые он содержит.

Предварительно скомпилированный заголовочный файл ищется, когда в компиляции встречается #include. При поиске включаемого файла (см. Путь поиска в Препроцессоре C) компилятор ищет предварительно скомпилированный заголовок в каждом каталоге, прежде чем искать включаемый файл в этом каталоге. Ищется имя, указанное в #include, с добавленным ‘.gch’. Если предварительно скомпилированный заголовочный файл не может быть использован, он игнорируется.

Например, если у вас #include "all.h", и у вас all.h.gch в той же директории, что и all.h, то предварительно скомпилированный заголовочный файл используется, если это возможно, а в противном случае используется исходный заголовочный файл.

В качестве альтернативы, вы можете поместить предварительно скомпилированный заголовочный файл в каталог и использовать -I, чтобы убедиться, что этот каталог ищется до (или вместо) каталога, содержащего исходный заголовок. Затем, если вы хотите убедиться, что предварительно скомпилированный заголовочный файл всегда используется, вы можете поместить в этот каталог файл с тем же именем, что и исходный заголовок, содержащий команду #error.

Это также работает с -include. Таким образом, еще один способ использования предварительно скомпилированных заголовков, подходящий для проектов, не задуманных с учетом предварительно скомпилированных заголовков, заключается в том, чтобы взять большинство заголовочных файлов, используемых проектом, включить их из другого заголовочного файла, предварительно скомпилировать этот заголовочный файл и использовать -include для предварительно скомпилированного заголовка. Если заголовочные файлы имеют защитные механизмы от множественного включения, они пропускаются, поскольку они уже включены (в предварительно скомпилированный заголовок).

Если вам нужно предварительно скомпилировать один и тот же заголовочный файл для разных языков, целей или опций компилятора, вы можете вместо этого создать каталог с именем, подобным all.h.gch, и поместить каждый предварительно скомпилированный заголовок в этот каталог, возможно, используя -o. Не имеет значения, как вы назовете файлы в каталоге; каждый предварительно скомпилированный заголовок в каталоге рассматривается. Первый предварительно скомпилированный заголовок, обнаруженный в каталоге, который подходит для этой компиляции, используется; они ищутся без определенного порядка.

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

Предварительно скомпилированный заголовочный файл может быть использован только в следующих случаях:

  • В одной конкретной компиляции может быть использован только один предварительно скомпилированный заголовок.
  • Предварительно скомпилированный заголовок не может быть использован после появления первого токена C. Вы можете иметь директивы препроцессора перед предварительно скомпилированным заголовком; вы не можете включить предварительно скомпилированный заголовок изнутри другого заголовка.
  • Предварительно скомпилированный заголовочный файл должен быть сгенерирован для того же языка, что и текущая компиляция. Вы не можете использовать предварительно скомпилированный заголовок C для компиляции C++.
  • Предварительно скомпилированный заголовочный файл должен быть сгенерирован тем же бинарным файлом компилятора, что и текущая компиляция.
  • Любые макросы, определенные до включения предварительно скомпилированного заголовка, должны быть определены таким же образом, как и при генерации предварительно скомпилированного заголовка, или не должны влиять на предварительно скомпилированный заголовок, что обычно означает, что они вообще не появляются в предварительно скомпилированном заголовке. Опция -D является одним из способов определения макроса перед включением предварительно скомпилированного заголовка; использование #define также может это сделать. Существуют также некоторые опции, которые неявно определяют макросы, такие как -O и -Wdeprecated; то же правило относится к макросам, определенным таким образом.
  • Если при использовании предварительно скомпилированного заголовка выводятся отладочные данные, используя -g или аналогичное, то тот же тип отладочных данных должен был быть выведен при создании предварительно скомпилированного заголовка. Однако предварительно скомпилированный заголовок, созданный с -g, может быть использован в компиляции, когда отладочные данные не выводятся.
  • В целом, те же опции -m должны использоваться при создании и использовании предварительно скомпилированного заголовка. См. Машинно-зависимые опции для случаев, когда это правило ослаблено.
  • Каждая из следующих опций должна быть одинаковой при создании и использовании предварительно скомпилированного заголовка:
    -fexceptions
  • Некоторые другие опции командной строки, начинающиеся с -f, -p или -O, должны быть определены так же, как и при создании предварительно скомпилированного заголовка. В настоящее время неясно, какие опции можно изменять, а какие нет; самый безопасный выбор — использовать точно те же опции при генерации и использовании предварительно скомпилированного заголовка. Известно, что следующие опции безопасны:
    -fmessage-length=  -fpreprocessed  -fsched-interblock
    -fsched-spec  -fsched-spec-load  -fsched-spec-load-dangerous
    -fsched-verbose=number  -fschedule-insns  -fvisibility=
    -pedantic-errors
  • Случайная перестановка компоновки адресного пространства (ASLR) может привести к тому, что файлы PCH не будут бинарно идентичны. Если вы полагаетесь на стабильное содержимое файла PCH, отключите ASLR при создании файлов PCH.

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

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

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-13.3.0/gcc/Precompiled-Headers.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API