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

После прочтения эта хорошая статья (Уход и подача предварительно скомпилированных заголовков), у меня есть некоторые сомнения относительно того, как они могут реально работать в реальной жизни. В частности, как я могу узнать, что мне нужно запустить пересборку скомпилированного заголовка в следующих сценариях:

  • Я решил #define что-то в одном из моих файлов .cpp, которое изменяет способ, которым препроцессор интерпретирует некоторые заголовки, которые уже включены в мой предварительно скомпилированный заголовок
  • Я включаю другой заголовок в один из моих файлов .cpp, который #defines специальная директива препроцессора, которая изменяет способ, которым препроцессор интерпретирует заголовок, уже включенный в предварительно скомпилированный заголовок
  • Что еще хуже, предыдущая проблема может возникнуть рекурсивно, когда определенные заголовки #include другие заголовки

Если использование предварительно скомпилированных заголовков обеспечивает определенный стиль кодирования, такой как ограничение количества заголовков, включенных в файлы .cpp, до одного и никогда #defineВещи в файл .cpp?

Хотя компилятор Microsoft, вероятно, неплохо справляется с предварительно скомпилированными заголовками (применяя некоторые специфичные для MS вуду), потому что, насколько я знаю, он обеспечивает /Yc а также /Yu опций, которые должны выполнять всю работу по сантехнике, для GCC кажется, что эта функциональность требует большого количества ручной работы и творчества в Makefile, и я не смог найти шаблон, который должен был бы устранить все подводные камни использования pre скомпилированные заголовки.

Например, если у меня есть проект, который собирает несколько библиотек, чтобы не перестраивать их все после каждого изменения, я должен использовать несколько очень симпатичных sed трюки в Makefile, чтобы обнаружить, если один из заголовков #includeд текущей библиотекой был изменен (или #includeизмененный заголовок). Я боюсь даже думать о тех сложностях, которые на самом деле подразумевают предварительно собранные заголовки, чтобы скрипт сборки перестраивал их каждый раз, когда это необходимо.

5

Решение

Текущий 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,


добавлений (ноябрь 2014)

Четное GCC 4.9 хочет один предварительно скомпилированный заголовок. Предварительно проанализированный заголовок Diego Novillo et al. был заброшен

Будущие версии (пост C ++ 14) стандарта C ++ может определять механизм модуля. Смотрите, например n4047 предложение.

(дополнительные дополнения, декабрь 2015 г.) GCC-5 и будущее GCC-6.

12

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]