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