Существует ли инструмент для сборки, основанный на механизме, подобном inotify? - PullRequest
14 голосов
/ 24 февраля 2011

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

Очевидное решение этой проблемы - инструмент сборки, основанный на inotify -подобной функции ОС.Он выглядел бы при изменении определенного файла, и на основании этого списка он компилировал бы этот файл один.

Есть ли такой механизм там?Бонусные баллы за проекты с открытым исходным кодом.

Ответы [ 5 ]

14 голосов
/ 02 марта 2011

Вы имеете в виду, как Tup :

С домашней страницы:

"Tup - это система сборки на основе файлов - она ​​вводит список изменений файлов и ориентированный ациклический граф (DAG), затем обрабатывает DAG для выполнения соответствующих команд, необходимых для обновления зависимых файлов. DAG хранится в База данных SQLite. По умолчанию список изменений файлов создается путем сканирования файловой системы. Кроме того, этот список можно предварительно получить, запустив включенный демон мониторинга файлов. "

4 голосов
/ 02 марта 2011

Мне просто интересно, если это stat() файлы, которые занимают так много времени. Чтобы проверить это, я написал небольшой системный файл , который я написал, чтобы измерить время, необходимое для stat() файлов:

# call-counts.stp

global calls, times

probe kernel.function(@1) {
    times[probefunc()] = gettimeofday_ns()
}

probe kernel.function(@1).return {
    now = gettimeofday_ns()
    delta = now - times[probefunc()]
    calls[probefunc()] <<< delta
}

А затем используйте это так:

$ stap -c "make -rC ~/src/prj -j8 -k" ~/tmp/count-calls.stp sys_newstat
make: Entering directory `/home/user/src/prj'
make: Nothing to be done for `all'.
make: Leaving directory `/home/user/src/prj'
calls["sys_newstat"] @count=8318 @min=684 @max=910667 @sum=26952500 @avg=3240

В проекте, на котором я его запускал, 4593 исходных файла, и он требует ~ 27 мсек (26952500 нсек выше) для make, чтобы проверить все файлы вместе с соответствующими .d файлами. Я использую нерекурсивный make.

2 голосов
/ 24 июня 2014

Если вы используете OSX, вы можете использовать fswatch

https://github.com/alandipert/fswatch

Вот как использовать fswatch для изменения файла, а затем запустить make, если он обнаружит

fswatch -o anyFile | xargs -n1 -I{} make

Вы можете запустить fswatch из make-файла следующим образом:

watch: $(FILE)
  fswatch -o $^ | xargs -n1 -I{} make

(Конечно, $ (FILE) определяется внутри make-файла.) make может теперь следить за изменениями в файле следующим образом:

> make watch

Вы можете посмотреть другой файл, например так:

> make watch anotherFile
1 голос
/ 25 февраля 2011

Установите inotify-tools и напишите несколько строк bash для вызова make при обновлении определенных каталогов.

В качестве примечания, рекурсивное make плохо масштабируется иподвержен ошибкамПредпочитаю нерекурсивную марку .

0 голосов
/ 25 февраля 2011

Описанная вами зависимость от изменений уже является частью Make, но Make достаточно гибок, чтобы ее можно было использовать неэффективно.Если медлительность действительно вызвана рекурсией (make -C командами) - что это, вероятно, - то вам следует уменьшить рекурсию.(Вы можете попытаться вставить свою собственную условную логику, чтобы решить, выполнять ли make -C, но это было бы очень не элегантным решением.)

Грубо говоря, если ваши make-файлы выглядят так

# main makefile

foo:
    make -C bar baz

и это

# makefile in bar/

baz: quartz
    do something

вы можете изменить их на это:

# main makefile

foo: bar/quartz
    cd bar && do something

Есть много деталей, чтобы получить право, но теперь, если bar/quartz не был изменен,foo Правило не будет работать.

...