После прочтения эта хорошая статья (Уход и подача предварительно скомпилированных заголовков), у меня есть некоторые сомнения относительно того, как они могут реально работать в реальной жизни. В частности, как я могу узнать, что мне нужно запустить пересборку скомпилированного заголовка в следующих сценариях:
#define
что-то в одном из моих файлов .cpp, которое изменяет способ, которым препроцессор интерпретирует некоторые заголовки, которые уже включены в мой предварительно скомпилированный заголовок#define
s специальная директива препроцессора, которая изменяет способ, которым препроцессор интерпретирует заголовок, уже включенный в предварительно скомпилированный заголовок#include
другие заголовкиЕсли использование предварительно скомпилированных заголовков обеспечивает определенный стиль кодирования, такой как ограничение количества заголовков, включенных в файлы .cpp, до одного и никогда #define
Вещи в файл .cpp?
Хотя компилятор Microsoft, вероятно, неплохо справляется с предварительно скомпилированными заголовками (применяя некоторые специфичные для MS вуду), потому что, насколько я знаю, он обеспечивает /Yc
а также /Yu
опций, которые должны выполнять всю работу по сантехнике, для GCC кажется, что эта функциональность требует большого количества ручной работы и творчества в Makefile, и я не смог найти шаблон, который должен был бы устранить все подводные камни использования pre скомпилированные заголовки.
Например, если у меня есть проект, который собирает несколько библиотек, чтобы не перестраивать их все после каждого изменения, я должен использовать несколько очень симпатичных sed
трюки в Makefile, чтобы обнаружить, если один из заголовков #include
д текущей библиотекой был изменен (или #include
измененный заголовок). Я боюсь даже думать о тех сложностях, которые на самом деле подразумевают предварительно собранные заголовки, чтобы скрипт сборки перестраивал их каждый раз, когда это необходимо.
Текущий GCC (т.е. 4.7) и предыдущие версии прекрасно работают с предварительно скомпилированные заголовки только когда у вас есть не замужем общий заголовок для вашего приложения, и когда этот единственный заголовок (который включает в себя все системные и библиотечные, требуемые приложением) #include
-д (как первая лексема без комментариев ваших источников) каждым источником вашего приложения.
Так что вы должны иметь не замужем yourapp.h
и иметь каждый исходный файл (то есть каждый модуль компиляции) yourapp
начало с #include "yourapp.h"
с такими же параметрами предварительной обработки (т.е. -D
или же -I
или же -U
) в командной строке. Тот youapp.h
заголовочный файл обычно #include
-на много других, например системные заголовки (или GTK или Qt), такие как <stdlib.h>
или же <sys/poll.h>
или [в C ++] <algorithm>
или же <gtk/gtk.h>
или же <QtGui>
и т.п.
Напомним, что -H
это полезный вариант, чтобы получить gcc
расскажу что входит.
Ваши исходные файлы могут иметь некоторые дополнительные #include
после #include "yourapp.h"
если так хотел.
После того, как GCC включит [один] предварительно скомпилированный заголовок, вы, конечно, можете #define
макросы, #include
какой-то не скомпилированный заголовок, сделайте условную компиляцию с #ifdef
и т. д. Но эта предварительная обработка не будет «предварительно скомпилированной»!
Это может не соответствовать вашим потребностям или привычкам.
Некоторые люди (в частности, из Google, в частности, Диего Новилло) работают над PreParsed Header (pph) ветвь чтобы улучшить ситуацию, но текущая магистраль GCC еще не получила эту работу.
Объяснение этого поведения GCC заключается в том, что предварительно обработанный заголовок является, по сути, постоянной сериализованной контрольной точкой всей кучи GCC (связанной с управление памятью внутри GCC через GGC и GTY и gengtype
). Эта куча контрольных точек может быть загружена только тогда, когда gcc
находится в своем начальном пустом состоянии. Как только что-то известно gcc
(на самом деле cc1
или же cc1plus
) он больше не может загружать любой предварительно скомпилированный заголовочный файл *.h.gch
и вернется к анализу файла текстового заголовка *.h
,
Четное GCC 4.9 хочет один предварительно скомпилированный заголовок. Предварительно проанализированный заголовок Diego Novillo et al. был заброшен
Будущие версии (пост C ++ 14) стандарта C ++ может определять механизм модуля. Смотрите, например n4047 предложение.
(дополнительные дополнения, декабрь 2015 г.) GCC-5 и будущее GCC-6.
Других решений пока нет …