Spec-Zone.ru › GCC 14

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-14.2.0/gcc/Precompiled-Headers.html

Spec-Zone.ru

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