Pull to refresh

Comments 28

Круто, но без автоматизации создания таких файлов неудобно. Ещё есть способ в 10 раз увеличить скорость компиляции, а точнее повторных пересборок (один раз можно и потерпеть, не так ли?) — способ называется ccache,.

>При компилировании какого-либо файла вычисляется его хэш и, если такой файл уже присутствует в реестре скомпилированных файлов, то он не будет компилироваться заново, а будет использоваться старый бинарный файл. Это может ускорить сборку некоторых пакетов в 5—10 раз.

В инете видел обёртку для cl.exe.
github.com/frerich/clcache
В Java CLDC (Monty) используется полу-автоматизированный юнитибилд.
Уже подзабыл точно как там устроено всё, но примерно так:
В cpp-шниках инклудов нет. В спец файле перечислено какие инклуды кому нужны
Тулза анализирует зависимости инклудов и перемешивает CPP-шки и H-ки в правильном порядке,
а также разбивает это всё безобразие на несколько больших файлов — чтобы пересобирать, при случае, не всё.
ccache решает ) в waterfall'е приятно смотреть, когда слейвы с ccache рвут в хвост и в гриву остальных.
clcache дает минимальный профит, порою сомнительный + наслышан о проблемах. Если у кого есть опыт, поделитесь?
С ним не сталкивался. Может он и кривой, а вот оригинальный ccache в Генте таки просто чудеса творит.
Давно работаю с ccache, глюков не замечено. Единственный минус-для кеша надо много места отдавать
еще distсс в связке с ним
Я правильно понял, что header-only код как раз и есть аналог этого решения? То есть один main.cpp, а все остальное на классах в хедерах.
Вообще я ускорил компиляцию и особенно юнит-тесты, создающие большое число мелких файлов, использованием 100-мегового RAM-диска. Последнее время думаю за 30 баксов докупить еще пару ГБ и еще более активно начать их использовать, ибо прирост в тестах был в 4 раза (около 700 тестов, каждый создает 4 файла и пишет/читает из них).
Работает: вместо ~1 минуты на обычную компиляцию теперь тратится ~15 секунд.
Круто! А ведь метод крайне очевидный, как-то даже не задумывался на эту тему.

Спасибо!
Исправьте опечатку
>статистическими переменными
как насчет того что в этом методе перестанет работать модификатор static?
В некоторых случаях можно заменить безымянным неймспейсом.
Хотя нет, нельзя.
К сожалению, anonymous namespace не помогает с коллизиями символов.
Надо же! Я думал, что это я один такой криворукий, что мне удобнее иметь один файл .cpp и кучу .h в проекте, а оказалось что у такого подхода есть название, и более того он увеличивает скорость компиляции. Спасибо :)
А Вы, простите, бустом никогда не пользовались? Или хотя бы STL…
У unity билдов есть еще одно достоинство — у компилятора появляется больше возможностей для оптимизации. Теоретически, компилятор сможет практически всё что делает линкер с link time code generation.
Еще один прием — вместо дополнительных конфигураций (и головной боли от отключения всех новых *.cpp файлов при добавлении в проект), можно просто создать дополнительный _проект_ с одним единственным cpp файлом. И еще, можно вытащить все общие параметры проектов в отдельные property sheets. Они работают просто «из коробки» для PC и 360 проектов. PS3 VSI представляет собой небольшую головную боль, но и его тоже можно настроить (VSI может использовать user macros, которые заданы в property sheet).
На мой взгляд, у unity есть всего три недостатка (один из которых описан в статье):
1. Статические, инлайн и anonymous namespace функции, переменные и типы должны иметь уникальные имена. Автор статьи призывает ими не злоупотреблять, но лично я с этим не согласен. Эти механизмы очень хороши для того чтобы прятать внутренности систем от пользователей публичных интерфейсов. Конечно, есть множество альтернатив для достижения того-же эффекта, но лично мне anonymous namespace-ы кажутся элегантным решением.
2. Когда один из cpp файлов include-ит какой-то заголовок, он становится доступным для всех последующих cpp файлов. Таким образом unity проект может компилироваться без проблем, но не-unity может выдавать ошибку о том, что некоторые символы не определены, т.к. необходимый заголовок на самом деле не включен. Это довольно серьезная проблема когда не-unity конфиг собирается долго и разработчики коммитят только тестируя в unity. На мой взгляд, самое простое решение этой проблемы — только поддерживать unity! У нас в проекте, например, несколько unity файлов (т.к. они могут компилироваться параллельно с помощью -j, /MP, SN-DBS или IncrediBuild).
3. При работе с одним отдельным cpp файлом, собирается весь unity файл. Это частично решается созданием нескольких unity файлов (как у нас в проекте) и созданием одного специального пустого unity файла. При необходимости в быстрой итерации, можно убрать отдельные файлы из «главного» файла и включить в специальный. Кроме того, это можно сделать по #ifdef YOUR_NAME для группы файлов и смело коммитить в депо.
Есть C++ проект на 2млн. строк кода. При рутинной пересборке с использованием cmake/g++, весь процесс занимает около минуты (ну там правда и машина соответствующая, на простом ноутбуке — 15 минут :-) ). А от вашего подхода компилятор мягко говоря охуееет… Надо кстати попробовать…
Полная пересборка на одной машине — около часа. Но вообще релизы 10 машин одновременно собирают, так что это около 10 минут выходит :-).
А никто не подумал о том, что при правке одного файлика у нас ребилдится весь проект? Зачем такое счастье?
1. См. предпоследний абзац — предыдущие конфигурации тоже остались. Хотите поправить один файлик — билдите обычным способом.
2. Представьте себе билд-сервер — там всегда всё с нуля собирается, этот способ даёт профит.
Билд-сервер, как правило, собирает быстрее, засчет его мощности. А во-вторых, не так уж и часто нужна версия с билд-сервера, чтобы ее прям сидеть и ждать.
Билд-сервер, как правило, собирает 100500 проектов по нескольку раз в день. Ускорение сборки каждого в пару раз = профит.
Sign up to leave a comment.

Articles