Как gnu Make обрабатывает зависимости?

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

for example, 
a.o: h1.h h2.h
    gcc...
b.o: h1.h h2.h
    gcc...

Если мы кешируем статус h1.h и h2.h при сборке a.o, сохраняем ли мы две проверки при сборке b.o?

Я не знаком с системой make, но в настоящее время ищу способы улучшить ее производительность в большом устаревшем проекте C.


person wei    schedule 09.08.2012    source источник
comment
это действительно проблема? Сколько зависимостей вы отслеживаете? Сколько теперь строится?   -  person n8wrl    schedule 10.08.2012
comment
да, файловый ввод-вывод - проблема, он медленный. Наш исходный код стал размером 2,5 ГБ, и для типичного файла C у нас есть около 800 зависимостей. Обычно на изготовление уходит 3-4 часа. Но, конечно, это не единственная проблема, которая у нас есть, и уж точно не самая большая, мы просто хотим поэкспериментировать с разными вариантами.   -  person wei    schedule 10.08.2012
comment
Если это всегда одни и те же файлы .h, вы уже пробовали a.o, b.o: h1.h h2.h?   -  person ott--    schedule 10.08.2012
comment
Это не всегда одни и те же файлы .h. это просто пример, иллюстрирующий мой вопрос.   -  person wei    schedule 10.08.2012
comment
ElectricMake и ElectricInsight вместе упрощают анализ производительности вашего процесса сборки. Прежде чем тратить слишком много времени на просмотр журналов strace, вам следует попробовать и посмотреть, поможет ли это вам сосредоточить свои усилия на самых больших и наименее висящих плодах. electric-cloud.com/products/electricaccelerator-dev.php   -  person Eric Melski    schedule 10.08.2012


Ответы (1)


Используйте strace для этой цели:

strace -e trace=stat make --touch

Вывод первого запуска (полная сборка):

...
stat("a.o", 0x7fff70c35f00)             = -1 ENOENT (No such file or directory)
stat("h1.h", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat("h2.h", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
touch a.o
stat("b.o", 0x7fff70c35f00)             = -1 ENOENT (No such file or directory)
touch b.o

И второй запуск (инкрементная сборка):

...
stat("a.o", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat("h1.h", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat("h2.h", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat("b.o", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
make: Nothing to be done for `all'.

Как видите, GNU Make кэширует временные метки, избегая ненужных stat системных вызовов. Однако, я думаю, дела обстоят не так хорошо в случае использования рекурсивного make.

person Eldar Abusalimov    schedule 09.08.2012
comment
Спасибо, очень жаль, у нас есть рекурсивный make, но, по крайней мере, теперь мы знаем, что GNU Make кэширует. - person wei; 10.08.2012