Spec-Zone.ru › GCC 15

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

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

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

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

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

Можно также поместить предварительно скомпилированный заголовочный файл в отдельный каталог и использовать -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-15.3.0/gcc/Precompiled-Headers.html

Spec-Zone.ru

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