Я консультируюсь с компанией о том, как ускорить их сборки, и я сразу же указал им на предварительно скомпилированные заголовки и сборки для единства - 10-минутная полная сборка может легко упасть до 2-3 минут. К счастью, недавно был выпущен CMake 3.16, и поддерживает оба этих , поэтому я сказал им обновить.
Проблема заключается в следующем: после того, как они переключились с CMake 2.6 на 3.16, потребовалось время для запуска CMake подскочил с 20 секунд до более 10 минут. Большая часть времени проводится в фазе генерации. Он завершается успешно, если вы дали ему достаточно времени, и код успешно скомпилирован с помощью сборок Unity, но это время CMake недопустимо.
Вот их настройка:
- CMake 2.6, old Стиль CMake с глобальными флагами / определяет / включает - не современный (на основе цели). Ничего особенного - никаких пользовательских команд или правил сборки и сложных зависимостей.
- используется компилятор G CC 7, и они генерируют Makefile - ОС CentOS 7, ядро: Linux 3.10.0-862.14 .4.el7.x86_64
- около 2000
.cpp
файлов, распределенных по 100 библиотекам и 600 исполняемым файлам (большинство из которых - тестовые исполняемые файлы с одним .cpp
в них) - большинство
.cpp
файлы собраны / скопированы с помощью aux_source_directory
- мы не знаем, что явное перечисление .cpp
файлов является анти-паттерном, но это не имеет значения - я думаю, что это не имеет значения, поскольку это должно происходить в Шаг конфигурации, а не во время генерации, правильно?
Вот что мы наблюдали:
- мы сделали бинарный поиск по различным версиям CMake и пришли к выводу, что огромное замедление произошло между 3.15 и 3.16 - именно тогда, когда была добавлена поддержка предварительно скомпилированного заголовка и единой сборки, но я не думаю, что эти функции имеют какое-либо отношение к замедлению - Я не могу придумать причину, по которой они оказали такое влияние - это должен быть какой-то другой рефакторинг или изменение ...
- мы отключили все тесты (это означает, что почти все 600 исполняемых файлов были удалены) - похудение число целей CMake от 700 до чуть более 100 - и время, необходимое для запуска CMake, значительно сократилось, но все же было в пару раз больше, чем с CMake 2.6 для всех 700 целей.
- we наблюдал за тем, что происходило с использованием
strace
, и были в основном вызовы lstat
и access
вместе с некоторыми операциями чтения и записи - но это было бесконечно - казалось сотнями операций в секунду в очень повторяемой манере. Также постоянно была попытка найти libgflags.so
, который постоянно терпел неудачу. К сожалению, сейчас у меня нет таких журналов. - мы создали профиль callgrind, и вот как он выглядит после пары минут работы: https://i.imgur.com/Z9AObso.png (вывод callgrind) файл можно найти здесь ) - похоже, большую часть времени тратится на
ComputeLinkLibs()
и получение полного имени и определений целей и еще много чего ... Не слишком ли много 700 целей? Это экспоненциальная проблема? Почему это не проблема с CMake 3.15?
Я не смог найти сообщений о том, что у кого-то есть такая же проблема на inte rnet ... Есть идеи, что попробовать дальше? Возможно профиль с использованием Perf? Попробуйте использовать ниндзя в качестве бэкэнда ( отчет о том, что он быстрее )?