Подтвердить что ты не робот

Какова наилучшая практика использования предварительно скомпилированных заголовков в современном приложении С++ Builder?

В настоящее время я переношу большой проект RAD Studio 2010 на XE4. Как часть этого, я воссоздаю многие файлы проекта. Я хотел бы воспользоваться возможностью, чтобы убедиться, что мы используем наилучший возможный механизм для предварительно скомпилированных заголовков, поскольку, как представляется, существует несколько способов сделать это.

Прямо сейчас мы компилируем только для 32-битных, но в будущем будем использовать 64-битный компилятор.

Вот что мы делаем в 2010 году, и почему я не уверен, что делать в XE4:

В RAD Studio 2010

У нас есть файл PchApp.h, который включает в себя <vcl.h> и ряд других обычно используемых файлов заголовков, в основном заголовки для различных обычно используемых основных классов в проекте. Этот заголовок включен в начало каждого файла CPP, за которым следует #pragma hdrstop, например:

// Top of .cpp file
#include "PchApp.h"
#pragma hdrstop

// Normal includes here
#include "other.h"
#include "other2.h"
// etc

Затем у нас есть следующие настройки в разделе Precompiled Headers параметров проекта:

Current RS2010 precompiled header settings

Это не особенно быстро компилировать (12 минут для около 350 000 строк кода.) Я не уверен о:

  • "Вставить предварительно скомпилированный файл заголовка": должно ли это вставить PchApp.h?
  • "Предварительно скомпилированные заголовки кэша (должны использоваться с -H или -H" xxx ")": параметр -H является "PCH filename", поэтому мы его используем, но, безусловно, точка предварительно скомпилированного заголовка заключается в том, что он "кэшируется" или предварительно создается один раз для компиляции. Какая дополнительная разница делает это?
  • Должны ли мы включить две строки для включения PchApp.h и pragma hdrstop в .cpp файлы? Есть ли способ сделать это только в вариантах проекта, а не дублировать эти две строки в каждом отдельном файле? Нужны ли они?

Другими словами, я не уверен, что это правильные или оптимальные настройки, но из чтения документации Я точно не уверен, что было бы лучше. Я знаю, что я не понимаю всех вариантов достаточно хорошо - одна из причин этого вопроса:)

В RAD Studio XE4

Диалог 32-битных параметров компилятора XE4 одинаковый, но две вещи меня путают и/или заставляют меня сомневаться в том, что нынешний подход 2010 года является лучшим.

1. Поведение по умолчанию

При создании нового проекта VCL Forms среда IDE создает заголовок названный по умолчанию Project1PCH1.h, который предназначен для предкомпилированного заголовка проекта. Этот заголовок включает <vcl.h> и <tchar.h> и отображается как node в диспетчере проектов. Он не включен в файл Form1.cpp по умолчанию, но #include <vcl.h>, за которым следует #pragma hdrstop, находится на самой вершине Form1.cpp, за которой следуют другие заголовки.

Диалог настроек XE4 по умолчанию для нового проекта с использованием этого заголовка: XE4 default precompiled header settings

Я (наивно?), работая в предположении, что по умолчанию действительно лучшие/самые оптимальные настройки. Некоторые вещи меня озадачили:

  • Предполагаемый предварительно скомпилированный заголовок проекта Project1PCH1.h не упоминается в настройках предварительно скомпилированного заголовка.
  • Заголовки не кэшируются
  • Имя файла PCH не указано (должно ли оно быть Project1PCH1.h?)
  • Файлы .cpp не включают Project1PCH1.h.

На самом деле я понятия не имею, как компилятор или IDE действительно знают, что он должен использовать Project1PCH1.h, или для каких файлов .cpp он должен использовать его, поскольку он никоим образом не упоминается найти.

Это самая загадочная вещь для меня, и это побудило задавать этот вопрос и прояснить всю мою путаницу в отношении PCHes. Я планировал скопировать/использовать настройки по умолчанию IDE, но я не хочу, пока не пойму, что они делают.

2. Мастер PCH

С 2010 года среда IDE включает в себя мастер с предварительно скомпилированным заголовком. Я никогда не мог заставить его работать - я запускаю его снова сейчас, чтобы получить его результаты и объяснить свою память о том, что "не работает", но, похоже, занимает несколько часов, поэтому я обновлю этот вопрос позже.

Изменить: он работает, хотя он занимает несколько часов, и создал список (для меня, зная исходную базу) нечетных заголовков. Мое воспоминание о том, как его пытались несколько лет назад, состоит в том, что он не запускался вообще - определенное улучшение.

Поскольку он существует, это может быть лучший способ настроить использование предварительно скомпилированных заголовков во вновь созданный файл проекта, созданный для обновления проекта 2010 года. Как мне лучше всего это сделать? Будут ли запущены все файлы .cpp, включая PchApp.h?

Вопросы

С этим в качестве фона у меня есть следующие вопросы:

  • Существующие настройки.Я создаю новый файл проекта и добавляю тысячи ранее существовавших .cpp файлов, все с "#include PchApp.h; #pragma hdrstop" наверху. Должен ли я копировать существующие настройки PCH RS2010? Должен ли я удалить две вышеуказанные строки и заменить их на что-то еще?
  • Использование мастера PCH:. Создает ли ваш опыт оптимальные настройки? Включает ли он файлы, которые, если они будут изменены, приведут к перестройке больших площадей проекта (вероятно, это не оптимально для кодирования)? Можно ли использовать в существующем проекте, или нужно ли удалять такие элементы, как наш "#include PchApp.h", прежде чем использовать его?
  • CPP файлы/единицы и правильная включает.. Файлы .cpp, которые используют предварительно скомпилированные заголовки, не включают сам предварительно скомпилированный заголовок, но только заголовки, которые действительно нужны .cpp, даже если PCH включает те? Что делать, если у вас есть текущая ситуация, когда файл PchApp.h содержит несколько общих заголовков, и поэтому .cpp файлы фактически не включают их сами? Если вы удалите включение PchApp.h и замените его подмножеством заголовков в PchApp.h, то нужны конкретные файлы .cpp, если они находятся выше или ниже #pragma hdrstop? (Выше, я думаю.) Что делать, если вы затем включите что-то еще выше с ними, которое не включено в предварительно скомпилированный заголовок - изменит ли он использование PCH для этой конкретной единицы, заставив PCH быть перестроен (проблемы с производительностью?) И т.д.?
  • Настройка по умолчанию: Предполагая, что настройка по умолчанию для нового проекта оптимальна, как лучше всего перенести текущую систему на ее использование?
  • Нестандартная настройка: Если настройка по умолчанию не оптимальна, что это такое? Это, я думаю, является ключевым вопросом.
  • 32 и 64-разрядные: Зная, что скоро перейдем к 64-битной версии, что нам делать, чтобы предварительно скомпилированные заголовки работали как на 32, так и на 64 бит? Должны ли все знания PCH быть в вариантах проекта, а не в файлах .cpp, поэтому разные настройки для 32- и 64-разрядной компиляции?

Я ищу четкий, подробный, пояснительный, руководящий ответ, в котором четко объясняются лучшие практика, параметры настройки, элементы для включения в .cpp файлы, заголовок и/или файл проекта и т.д. - другими словами, что-то, чтобы очистить меня к настоящему времени (после всего вышеизложенного!), довольно смутное понимание. Высококачественный ответ, который может использоваться в качестве ссылки на PCH в будущем другими пользователями С++ Builder в будущем, будет отличным. Я намерен добавить щедрость в через пару дней, когда я могу.

4b9b3361

Ответ 1

  • Существующие настройки.. По моему опыту, я обычно менял эти настройки, потому что, если у вас сотни файлов, это просто не оптимально. В xCode, то есть по умолчанию. Не должно быть различий в производительности компиляции.
  • Использование мастера PCH Честно говоря, я никогда не использовал его в реальном проекте, и он меня не впечатлил, поэтому просто забыл об этом и использовал ручные настройки.
  • CPP файлы/единицы и правильная включает.. Для разных IDE для этого есть разные настройки по умолчанию. Обычно я использую:
    • Автоматически вставлять предварительно скомпилированные заголовки (нет руководства #include в .cpp)
    • Сначала включите соответствующий заголовок, соответствующий .cpp, если он существует (myfile.cpp - then include myfile.h)
    • После этого включите все конкретные заголовки, которые выполняют определенную работу (определенные заголовки lib и т.д.).
    • В "myfile.h" включить ТОЛЬКО материал, который является обязательным. Избегайте любых вещей, которых вы можете избежать.
    • Все, что вы указываете специально для конкретного .cpp файла, должно быть ниже #pragma hdrstop. Все, что вы хотите предварительно скомпилировать, должно быть выше.
  • Настройка по умолчанию Я не думаю, что это оптимально. Что касается меня, то гораздо проще мигрировать, просто изменяя пару параметров в настройках.
  • Нестандартная настройка Как я уже упоминал выше - для меня оптимальная настройка - с автоматической вставкой предварительно скомпилированного заголовка. Подробнее в пункте 3.
  • 32 и 64-разрядные не испытывали никаких проблем с этим. Он должен генерировать собственные предварительно скомпилированные заголовки для каждой конкретной конфигурации.

Ответ 2

Вот что я делаю (хотя я не уверен, что это хорошая идея или нет, но, похоже, это работает)

  • Убедитесь, что Project1PCH1.h существует (где Project1 - это название проекта)
  • Заставьте его содержать #pragma hdrstop и 2 завершающих символа новой строки (у меня появились странные ошибки, когда у меня не было завершающих символов новой строки, возможно, ошибка компилятора)
  • В "Все конфигурации", помещенный в "Предварительно скомпилированный файл заголовка", затем назовите "Project1PCH1.h"
  • Не делайте ничего, например #include "PchApp.h" и #pragma hdrstop в других файлах.
  • Проверить, что все правильно построено (то есть, файлы имеют право, включаются по своему усмотрению, не полагаясь на введенный PCH).
  • Поместите некоторые объекты в Project1PCH1.h. Я использую мастер, чтобы придумать некоторые предложения, но вы также должны применить некоторую человеческую логику, чтобы получить хорошую сборку.

Когда он работает правильно в 32-битном режиме, все быстро компилируется; вы можете сказать, если вы не совсем правильно поняли, если вы компилируете свой проект, а один конкретный .cpp файл занимает намного больше времени, чем остальные. Мастер делает предложения, основанные на том, сколько файлов содержит данный заголовок, но это несколько фиктивный; вам нужно включить в него любой системный заголовок (или заголовок boost и т.д.), который значительно увеличит время компиляции, если он не будет частью PCH.

Я не хочу включать в него свои собственные заголовки проектов, просто системные и стандартные заголовки. Это может отличаться для вас в зависимости от вашего проекта, IDK.

PCH не работает для файлов .c, поэтому, если у вас есть какие-либо из них в вашем файле, вам нужно будет сделать Project1PCH1.h, у которого есть #ifdef __cplusplus.

Также: даже если bcc64 не поддерживает PCH (но он вставляет файл), если у вас есть ваш PCH, настроенный правильно, похоже, что компиляция идет быстрее, я не совсем уверен, почему.


Что я еще не понимаю об этом:

  • Почему мастер New Project автоматически генерирует Project1PCH1.h, но не устанавливает его в поле "Предварительно скомпилированный заголовок заголовка" свойств проекта?
  • Иногда сборка не отвечает, что она не может открыть Project1PCH1.h, но если я вношу некоторые изменения и повторно сохраняю их, как правило, это исправляет.