Я работаю над очень крупномасштабными проектами, время компиляции которых составляет очень. Какие инструменты я могу использовать (желательно с открытым исходным кодом) в Linux, чтобы найти наиболее часто включаемые файлы и оптимизировать их использование? Для большей ясности мне нужен инструмент, который, учитывая зависимости, покажет мне, какие заголовки используются чаще всего. Кстати, мы используем распределенную компиляцию
Возможно, вам следует отредактировать свой вопрос, чтобы включить эту информацию, а не использовать ее в качестве комментария?





IIRC gcc может создавать файлы зависимостей.
Вы можете посмотреть на распределенную компиляцию, см., Например, distcc
Проверить Макдепенд
Это дает мне зависимость для каждого файла. Мне нужно что-то, что с учетом этого найдет самые включаемые файлы.
Такие инструменты, как доксиген (используемые с параметрами graphviz), могут генерировать графы зависимостей для включаемых файлов ... Я не знаю, предоставят ли они достаточный обзор того, что вы пытаетесь сделать, но, возможно, стоит попробовать.
Это не совсем то, что вы ищете, и его может быть непросто настроить, но, возможно, вы могли бы взглянуть на lxr: lxr.linux.no - это дерево ядра с возможностью просмотра.
Если в поле поиска вы введете имя файла, вы увидите, где оно находится. Но это все еще предположение, и он не отслеживает связанные зависимости.
Может быть
strace -e trace=open -o outfile make
grep 'some handy regex to match header'
Если вы хотите узнать, какие файлы включаются больше всего, используйте эту команду bash:
find . -name '.cpp' -exec egrep '^[:space:]#include[[:space:]]+["<][[:alpha:][:digit:]_.]+[">]' {} \;
| sort | uniq -c | sort -k 1rn,1
| head -20
Он отобразит 20 лучших файлов, ранжированных по количеству включений.
Объяснение: Первая строка находит все файлы * .cpp и извлекает из них строки с директивой "#include". Вторая строка вычисляет, сколько раз каждый файл был включен, а третья строка занимает 20 наиболее часто включаемых файлов.
Не проверял это, но ваше решение не будет работать, если один и тот же файл включен с использованием двух разных путей. Т.е. #include <dev / blah.h> и #include <./ dev / blah.h> будут считаться разными включаемыми файлами.
Хотя, в принципе, неплохая идея.
Используя философию Unix «склеивания множества небольших инструментов», я бы предложил написать короткий сценарий, который вызывает gcc с параметрами -M (или -MM) и -MF (OUTFILE) (как подробно описано в здесь). Это сгенерирует списки зависимостей для инструмента make, которые затем можно будет легко проанализировать (по сравнению с анализом исходных файлов напрямую) и извлечь необходимую информацию.
МОЙ БОГ! Где я был за десятилетия взлома? Прямо из авторитетного источника. Небольшое количество качественного времени с этими вариантами (как подробно описано в твердом ответе Дэмина) и несколько рутинных, но уместных хакерских действий, и вот оно. Спасибо Дэмин.
Ответы здесь предоставят вам инструменты, которые отслеживают зависимости #include. Но здесь нет упоминания об оптимизации и тому подобном.
В сторону: книга «Крупномасштабный дизайн программного обеспечения на C++» должна помочь.
Из корневого уровня исходного дерева выполните следующие действия (\ t - символ табуляции):
find . -exec grep '[ \t]*#include[ \t][ \t]*["<][^">][">]' {} ';'
| sed 's/^[ \t]*#include[ \t][ \t]*["<]//'
| sed 's/[">].*$//'
| sort
| uniq -c
| sort -r -k1 -n
Строка 1 получает все включаемые строки. Строка 2 удаляет все, что находится перед фактическим именем файла. Строка 3 удаляет конец строки, оставляя только имя файла. В строках 4 и 5 учитывается каждая уникальная строка. Строка 6 сортируется по количеству строк в обратном порядке.
Вам нужно [^ ">] * вместо [^">] в grep.
Это также не отслеживает включения, которые создаются ниже по течению. Разбор вывода "gcc -E -dI" будет намного лучше для более сложного проекта.
Используйте ccache. Он будет хешировать входные данные для компиляции и кэшировать результаты, что резко увеличит скорость подобных компиляций.
Если вы хотите обнаружить несколько включений, чтобы их можно было удалить, вы можете использовать makedepend, как предлагает Юлиан Чербанойу:
makedepend -m *.c -f - > /dev/null
выдаст предупреждение для каждого множественного включения.
Сценарии Bash, найденные на странице, не являются хорошим решением. Работает только на простом проекте. Фактически, в большом проекте, например, в описании в заголовке страницы, часто используется препроцессор C (#if, #else, ...). Только хорошее программное обеспечение, более сложное, например makedepend или бра, может дать хорошую информацию. gcc -E может помочь, но в большом проекте анализ результатов - пустая трата времени.
Для большей ясности мне нужен инструмент, который, учитывая зависимости, покажет мне, какие заголовки используются чаще всего. Кстати, мы используем распределенную компиляцию