использование скомпилированных заголовочных файлов для сборщиков библиотек - PullRequest
4 голосов
/ 02 сентября 2011

Согласно этот ответ заголовки boost и STL входят в предварительно скомпилированный заголовочный файл (stdafx.h в мире MSVC).Поэтому я изменил заголовки моего проекта библиотеки динамических ссылок и переместил все заголовки STL / Boost в stdafx.h моего проекта.

До

#include <boost/smart_ptr.hpp>

namespace XXX
{
  class CLASS_DECL_BK CExampleClass // CLASS_DECL_BK is just a standard dll import/export macro
  {
    private:
      boost::scoped_ptr<Replica> m_replica;
  }
}

После

namespace XXX
{
  class CLASS_DECL_BK CExampleClass
  {
    private:
      boost::scoped_ptr<Replica> m_replica;
  }
}

Теперь у меня есть преимущество в уменьшении времени компиляции, , но все пользователи моей библиотеки получают ошибки сборки (например, неизвестный boost :: scoped_ptr...) из-за отсутствующих включений (которые теперь перенесены в мой stdafx.h).


Что может быть решением этой дилеммы?

Я хочу уменьшить время компиляции и ошибки компиляции после включения моих файлов заголовков не приемлемы для любых пользователей DLL.

Может ли это помочь?

  • оставить всевключает директивы как они есть, но дублируют их в моем 'stdafx.h'?Так как stdafx.h всегда включается первым внутри любого cpp-файла моего проекта, я должен быть в порядке, и пользователи не получат никаких ошибок.Или я теряю преимущество в скорости, если несколько включений одного и того же заголовка происходят в одном блоке перевода (получил защиту заголовков)?

Спасибо за любые подсказки!

Ответы [ 3 ]

2 голосов
/ 02 сентября 2011

Вы должны получить почти такое же увеличение скорости, когда оставляете заголовочные включения на месте в заголовках библиотеки и просто дополнительно помещаете их в stdafx.h.

В качестве альтернативы, вы можете добавить дополнительное определение (массовое внешнее включение защиты )

// stdafx.h
#define MY_LIB_STD_HEADERS_ALREADY_INCLUDED

// library_file.h
#ifndef MY_LIB_STD_HEADERS_ALREADY_INCLUDED
#include <boost/smart_ptr.hpp>
...
#endif

Но я бы сделал это, только если вы уверены, , это помогает. Просто возьмите секундомер и запустите несколько перекомпиляций. (Нет необходимости в ссылке.) Тогда вы увидите, есть ли разница.

Помимо

Я не уверен, является ли хорошей идеей добавить все заголовки повышения, которые необходимы где-то в проекте. Я бы сказал, shared_ptr и друзья, boost/foreach, может быть, Boost.Format, ... хорошая идея, но я бы уже дважды подумал о заголовках Boost.RegExp. Примечание: я не не делал никаких измерений скорости , но я смутно помню проблему с размером файла pch и некоторой ошибкой компилятора. Я действительно должен сделать несколько тестов .

Также проверьте, предоставляет ли соответствующая библиотека повышения заголовки переадресации и следует ли вместо них включать их. Раздувание предварительно скомпилированного заголовочного файла может иметь свои недостатки.

2 голосов
/ 02 сентября 2011

вы можете создать конфигурацию сборки для этой цели (Debug, Release, CheckDependencies).простой способ изменить это - использовать препроцессор для включения / исключения включений на основе текущей конфигурации.используя это, вы можете протестировать и собрать с помощью debug или release (который содержит больший набор включений), а затем собрать все конфигурации перед распространением.

, чтобы уточнить, условное включение MON_LIBRARY_VALIDATE_DEPENDENCIES не должно использоваться взаголовки или источники библиотеки, только в предварительно скомпилированном заголовке:

// my pch:
#include <file1.hpp>
#include <file2.hpp>
// ...

#if !defined(MON_LIBRARY_VALIDATE_DEPENDENCIES)
#include <boost/stuff.hpp>
// ...
#endif

, тогда вы добавите MON_LIBRARY_VALIDATE_DEPENDENCIES к списку определений препроцессора в конфигурации CheckDependencies.

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

1 голос
/ 02 сентября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...