# включить все файлы.cpp в один модуль компиляции?

Недавно у меня была причина поработать с некоторыми проектами Visual Studio C++ с обычными конфигурациями Debug и Release, а также с "Release All" и "Debug All", которых я никогда раньше не видел.

Оказывается, у автора проектов есть единственный ALL.cpp, который включает в себя все остальные.cpp файлы. * Все конфигурации просто создают этот единственный файл ALL.cpp. Это, конечно, исключено из обычных конфигураций, и обычные конфигурации не собирают ALL.cpp

Мне просто интересно, было ли это обычной практикой? Какие преимущества это дает? (Моей первой реакцией было то, что пахло плохо.)

С какими подводными камнями вы можете столкнуться? Одна вещь, о которой я могу подумать: если у вас есть анонимные пространства имен в ваших.cpps, они больше не являются "приватными" для этого cpp, но теперь видны и в других cpps?

Все проекты строят библиотеки DLL, так что наличие данных в анонимных пространствах имен не будет хорошей идеей, верно? Но функции будут в порядке?

Приветствия.

5 ответов

Решение

Некоторые называют его (и в состоянии Google) как "Unity Build". Он связывает безумно быстро и достаточно быстро компилируется. Он отлично подходит для сборок, в которых вам не нужно повторяться, например, для сборки выпуска с центрального сервера, но не обязательно для инкрементной сборки.

И это PITA для поддержания.

РЕДАКТИРОВАТЬ: вот первая ссылка Google для получения дополнительной информации: http://buffered.io/posts/the-magic-of-unity-builds/

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

Брюсу Доусону гораздо лучше написать об этом в своем блоге: http://randomascii.wordpress.com/2014/03/22/make-vc-compiles-fast-through-parallel-compilation/

Unity повышает скорость сборки по трем основным причинам. Первая причина заключается в том, что все файлы общего заголовка необходимо проанализировать только один раз. Многие проекты C++ имеют много заголовочных файлов, которые включены в большинство или во все файлы CPP, и их избыточный анализ является основной стоимостью компиляции, особенно если у вас много коротких исходных файлов. Прекомпилированные заголовочные файлы могут помочь с этой стоимостью, но обычно есть много заголовочных файлов, которые предварительно не скомпилированы.

Следующая основная причина того, что Unity builds улучшает скорость сборки, заключается в том, что компилятор вызывается меньше раз. Существует некоторая стоимость запуска с вызовом компилятора.

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

Сборки Unity также могут дать лучший код.

Unity не работает быстрее из-за уменьшения дискового ввода-вывода. Я профилировал многие сборки с помощью xperf и знаю, о чем говорю. Если у вас достаточно памяти, то дисковый кеш ОС избежит избыточного ввода-вывода - последующие чтения заголовка будут поступать из дискового кеша ОС. Если у вас недостаточно памяти, то единственные сборки могут даже ухудшить время сборки, в результате чего объем памяти компилятора превысит доступную память и будет выгружен.

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

Интересно, пытается ли этот ALL.cpp поместить весь проект в один модуль компиляции, чтобы улучшить способность компилятора оптимизировать программу по размеру?

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

Тем не менее, я помню, что последние компиляторы (Microsoft, Intel, но я не думаю, что это включает GCC) могут выполнять эту оптимизацию для нескольких модулей компиляции, поэтому я подозреваю, что этот "трюк" не нужен.

Тем не менее, было бы любопытно увидеть, действительно ли есть какая-то разница.

Я согласен с Брюсом; Исходя из своего опыта, я пытался внедрить Unity Build для одного из моих проектов.dll, у которого было множество заголовков и много.cpps; чтобы сократить общее время компиляции на VS2010(уже исчерпаны опции инкрементной сборки), но вместо того, чтобы сократить время компиляции, у меня закончилась память, и сборка даже не смогла завершить компиляцию.

Однако добавить; Я обнаружил, что включение опции многопроцессорной компиляции в Visual Studio весьма помогает сократить время компиляции; Я не уверен, доступна ли такая опция в других компиляторах платформы.

В дополнение к превосходному ответу Брюса Доусона следующая ссылка дает больше информации о плюсах и минусах построения единства - https://github.com/onqtam/ucm

У нас есть мультиплатформенный проект для MacOS и Windows. У нас есть много больших шаблонов и много заголовков для включения. Мы сократили время сборки с помощью Visual Studio 2017 msvc, используя предварительно скомпилированные заголовки. Для MacOS мы несколько дней пытались сократить время сборки, но предварительно скомпилированные заголовки только сократили время сборки до 85%. Использование одного.cpp-файла было прорывом. Мы просто создаем этот ALL.cpp с помощью скрипта. Наш ALL.cpp содержит список включений всех.cpp-файлов нашего проекта. Мы сократили время сборки до 30% с помощью XCode 9.0. Единственным недостатком было то, что мы должны были давать имена всем частным неименованным пространствам имен модулей компиляции в.cpp-Files. В противном случае локальные имена будут конфликтовать.

Другие вопросы по тегам