Есть ли встроенный инструмент, основанный на механизме, подобном inotify

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

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

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

Ответ 1

Вы имеете в виду Tup:

На главной странице:

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

Ответ 2

Мне просто интересно, есть ли stat() файлы, которые занимают так много времени. Чтобы проверить это, вот небольшой systemtap script Я написал для измерения времени, которое требуется для файлов 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 исходных файла, и для получения статистики всех файлов вместе с соответствующими файлами .d требуется ~ 27 мс (26952500 нсек). Я использую нерекурсивный make, хотя.

Ответ 3

Если вы используете 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

Ответ 4

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

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

Ответ 5

Зависимая от изменения зависимость уже входит в 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 не будет выполняться.