Spec-Zone.ru › GCC 7

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

Часто в крупных проектах имеется множество заголовочных файлов, которые включаются в каждый исходный файл. Время, которое компилятор тратит на обработку этих заголовочных файлов снова и снова, может составлять почти всё время, необходимое для построения проекта. Для ускорения сборки 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

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

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

Предыдущий: Переменные окружения, Вверх: Вызов GCC [Содержание][Индекс]

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

Spec-Zone.ru

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