Предварительно скомпилированный заголовок
В этой статье есть несколько проблем. Пожалуйста, помогите улучшить его или обсудите эти проблемы на странице обсуждения . ( Узнайте, как и когда удалять эти шаблонные сообщения )
|
В компьютерном программировании ( предварительно скомпилированный заголовок PCH) представляет собой ( C или C++ ) файл заголовка , который компилируется в промежуточную форму , которая быстрее обрабатывается компилятором . Использование предварительно скомпилированных заголовков может значительно сократить время компиляции , особенно при применении к большим файлам заголовков, файлам заголовков, которые включают в себя множество других файлов заголовков, или файлам заголовков, которые включены во многие единицы перевода .
Обоснование
[ редактировать ]В C и C++ языках программирования — файл заголовка это файл, текст которого может быть автоматически включен в другой исходный файл препроцессором C с помощью директивы препроцессора в исходном файле.
Файлы заголовков иногда могут содержать очень большие объемы исходного кода (например, файлы заголовков windows.h
и Cocoa/Cocoa.h
в Microsoft Windows и OS X соответственно). Это особенно актуально с появлением больших «заголовочных» библиотек, которые широко используют шаблоны , таких как математическая библиотека Eigen и библиотеки Boost C++ . Они почти полностью написаны как заголовочные файлы, которые пользователь #include
s, а не связываться во время выполнения. Таким образом, каждый раз, когда пользователь компилирует свою программу, он, по сути, также перекомпилирует многочисленные библиотеки заголовков. (Они будут предварительно скомпилированы в общие объекты или библиотеки динамической компоновки в библиотеках, не являющихся «заголовочными».)
Чтобы сократить время компиляции, некоторые компиляторы позволяют компилировать файлы заголовков в форму, которая быстрее обрабатывается компилятором. Эта промежуточная форма известна как предварительно скомпилированный заголовок и обычно хранится в файле с расширением .pch
или подобное, например .gch
в коллекции компиляторов GNU .
Использование
[ редактировать ]Например, для файла C++ source.cpp
что включает в себя header.hpp
:
//header.hpp
...
//source.cpp
#include "header.hpp"
...
При составлении source.cpp
впервые при включенной функции предварительно скомпилированного заголовка компилятор сгенерирует предварительно скомпилированный заголовок, header.pch
. В следующий раз, если временная метка этого заголовка не изменилась, компилятор может пропустить фазу компиляции, связанную с header.hpp
и вместо этого используйте header.pch
напрямую.
Общие реализации
[ редактировать ]Microsoft Visual C и C++
[ редактировать ]Microsoft Visual C++ (версия 6.0 и новее) [ нужна ссылка ] ) может прекомпилировать любой код, а не только заголовки. [1]
Это можно сделать двумя способами: либо предварительно скомпилировать весь код в файл, имя которого соответствует /Ycfilename
вариант или (когда /Yc
указывается без каких-либо filename
) предварительная компиляция всего кода до первого появления #pragma hdrstop
в коде [2] [3]
Предварительно скомпилированный результат сохраняется в файле с именем filename
предоставлено /Yc
вариант, с .pch
расширении или в файле, названном в соответствии с именем, предоставленным /Fpfilename
вариант. [3]
/Yu
вариант, подчиненный /Yc
Если этот параметр используется вместе, он заставляет компилятор использовать уже предварительно скомпилированный код из такого файла. [3]
pch.h
(названный stdafx.h
до Visual Studio 2017 [4] ) — это файл, созданный мастером Visual Studio IDE Microsoft , который описывает как стандартные системные, так и специфичные для проекта включаемые файлы , которые часто используются, но почти никогда не изменяются.
Afx stdafx.h в приложений означает расширения платформы . AFX — это первоначальное сокращение классов Microsoft Foundation (MFC). Хотя имя stdafx.h использовалось по умолчанию в проектах MSVC до версии 2017, любое альтернативное имя можно указать вручную.
Совместимые компиляторы предварительно скомпилируют этот файл, чтобы сократить общее время компиляции. Visual C++ не будет ничего компилировать до #include "pch.h"
в исходном файле, если только не указана опция компиляции /Yu'pch.h'
флажок снят (по умолчанию); предполагается, что весь код в исходном коде, вплоть до этой строки, уже скомпилирован.
GCC
[ редактировать ]Предварительно скомпилированные заголовки поддерживаются в GCC (3.4 и новее). Подход GCC аналогичен подходу VC и совместимых компиляторов. GCC сохраняет предварительно скомпилированные версии файлов заголовков, используя " .gch
". При компиляции исходного файла компилятор проверяет, присутствует ли этот файл в том же каталоге, и по возможности использует его.
GCC может использовать предварительно скомпилированную версию только в том случае, если установлены те же параметры компилятора, что и при компиляции заголовка, и он может использовать не более одного. Кроме того, перед предварительно скомпилированным заголовком можно размещать только инструкции препроцессора (поскольку он должен быть прямо или косвенно включен через другой обычный заголовок перед любым компилируемым кодом).
GCC автоматически идентифицирует большинство файлов заголовков по их расширению. Однако если это не удается (например, из-за нестандартных расширений заголовков), -x
Переключатель можно использовать, чтобы гарантировать, что GCC рассматривает файл как заголовок.
лязг
[ редактировать ]Компилятор clang добавил поддержку PCH в Clang 2.5/LLVM 2.5 2009 года. [5] Компилятор одновременно маркирует входной исходный код и выполняет синтаксический и семантический анализ заголовков, записывая внутреннее сгенерированное компилятором абстрактное синтаксическое дерево (AST) и таблицу символов в предварительно скомпилированный файл заголовка. [6]
Схема предварительно скомпилированных заголовков clang с некоторыми улучшениями, такими как возможность одного предварительно скомпилированного заголовка ссылаться на другой предварительно скомпилированный заголовок, используемый внутри компании, также формирует основу для механизма его модулей. [6] Он использует тот же формат файла битового кода , который используется LLVM , инкапсулированный в разделы, специфичные для clang, в файлах общего формата объектного файла или расширяемого формата связывания . [6]
C++Builder
[ редактировать ]В конфигурации проекта по умолчанию компилятор C++Builder неявно генерирует предварительно скомпилированные заголовки для всех заголовков, включенных в исходный модуль, до тех пор, пока не появится строка #pragma hdrstop
найден. [7] : 76 Предварительно скомпилированные заголовки по возможности используются всеми модулями проекта. Например, при работе с библиотекой визуальных компонентов обычно включаются vcl.h
header first, который содержит большинство часто используемых файлов заголовков VCL. Таким образом, предварительно скомпилированный заголовок может использоваться всеми модулями проекта, что значительно сокращает время сборки.
Кроме того, C++Builder можно настроить для использования определенного файла заголовка в качестве предварительно скомпилированного заголовка, аналогично механизму, предоставляемому Visual C++.
В C++Builder 2009 представлен «Мастер предварительно скомпилированных заголовков», который анализирует все исходные модули проекта на предмет включенных файлов заголовков, классифицирует их (т. е. исключает файлы заголовков, если они являются частью проекта или не имеют защиты Include ), а также генерирует и автоматически проверяет предварительно скомпилированный заголовок для указанных файлов.
Предварительно токенизированный заголовок
[ редактировать ]( Предварительно токенизированный заголовок PTH) — это заголовочный файл, хранящийся в форме, которая прошла лексический анализ , но над ним не было выполнено никаких семантических операций. PTH присутствует в Clang до того, как он стал поддерживать PCH, а также был опробован в ветке GCC. [8]
По сравнению с полным механизмом PCH, PTH имеет преимущества независимости от языка (и диалекта), поскольку лексический анализ аналогичен для языков семейства C, и независимости от архитектуры, поскольку при компиляции для разных целевых архитектур может использоваться один и тот же поток токенов. . [9] Однако у него есть тот недостаток, что он не идет дальше простого лексического анализа, требуя, чтобы синтаксический и семантический анализ потока токенов выполнялся при каждой компиляции. Кроме того, время компиляции масштабируется линейно с размером в лексических токенах предварительно токенизированного файла, что не обязательно имеет место для полноценного механизма предварительной компиляции (PCH в clang допускает произвольный доступ). [9]
Механизм предварительной токенизации Clang включает в себя несколько второстепенных механизмов помощи препроцессору: кэширование информации о существовании файла и дате, а также запись средств защиты включения , чтобы можно было быстро пропустить защищенный код. [9]
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ «Создание предварительно скомпилированных заголовочных файлов» . MSDN . Майкрософт. 2015. Архивировано из оригинала 28 марта 2018 г. Проверено 28 марта 2018 г.
- ^ «Два варианта предварительной компиляции кода» . MSDN . Майкрософт. 2015 . Проверено 28 марта 2018 г.
- ^ Перейти обратно: а б с «/Yc (Создать предварительно скомпилированный файл заголовка)» . MSDN . Майкрософт. 2015 . Проверено 28 марта 2018 г.
- ^ «Могу ли я использовать #include «pch.h» вместо #include «stdafx.h» в качестве заголовка прекомпиляции в Visual Studio C++?» . Переполнение стека .
- ^ «Примечания к выпуску LLVM 2.5» . Releases.llvm.org .
- ^ Перейти обратно: а б с Команда Clang (2018). «Предварительно скомпилированный заголовок и внутреннее устройство модулей» . Документация Clang 7 . Проверено 28 марта 2018 г.
- ^ Сварт, Боб (2003). Руководство разработчика Borland C++ Builder 6 . Издательство Самс. ISBN 9780672324802 .
- ^ «pph — GCC Wiki» . gcc.gnu.org .
- ^ Перейти обратно: а б с Команда Clang (2018). «Предварительно токенизированные заголовки (PTH)» . Документация Clang 7 . Архивировано из оригинала 22 марта 2018 г. Проверено 28 марта 2018 г.