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