Что: 679136a9a37c25390c7cd9a605e2d4269c0e565b
Когда: 2020-12-01 20:29:28+03:00
Темы: redo
Make vs redo на простой практике, снова https://habr.com/ru/company/ruvds/blog/528434/ В одном из комментариев увидел пример того как человек конвертирует .bmp в .png: BMPS := $(wildcard *.bmp) PNGS := $(patsubst %.bmp,%.png,$(BMPS)) .PHONY: all all: $(PNGS) %.png: %.bmp convert {body}lt; $@ touch -r {body}lt; $@ rm {body}lt; Это конечно не (POSIX) Make, а GNU Make. Почему это просто не сделать shell циклом? Наверное потому что make будет распараллеливать эти задачи. Но есть решение куда более короткое (требующее, вместо GNU Make, GNU Parallel): parallel "convert {} {.}.png && touch -r {} {.}.png && rm {}" ::: *.bmp По моему гораздо проще -- всё же однострочник, вмиг набираемый в командной строке. Автор комментария отметил что Make не может тут ничего поделать с именами с пробелами: с parallel их не возникнет. Аналог на redo будет такой: all.do: find . -name "*.bmp" -maxdepth 1 | while read f ; do echo ${f%.bmp}.png ; done | xargs redo-ifchange default.png.do: convert $2.bmp $3.png mv $3.png $3 touch -r $2.bmp $3 rm $2.bmp В отличии от GNU Make не требует знания сверх shell-а, без проблем будет работать с пробелами. Если убрать -maxdepth, то и с иерархией файлов в директориях будет отрабатывать без проблем (в parallel аналогично можно сделать просто указав **.bmp или направив find). "mv $3.png $3" я делаю только потому что мне лень искать как convert-у указать формат выходного файла, поэтому подсказываю ему расширением. all.do можно конечно и покороче записать, если файлов не много и они без пробелов: all.do: redo-ifchange `for f in *.bmp ; do echo ${f%.bmp}.png ; done` Но у этих решений есть большой недостаток: а что будет если компьютер упадёт? Нужны sync-и и только потом удалять оригинальный .bmp. Make оставит за собой побитый .png мусор, но так как .bmp не удалён, можно понять что задача не была завершена. (Корректная реализация) redo делает sync на $3 файл автоматом, как DJB и задумывал. goredo ещё явно делает и sync на директорию после переименования. Но тут проблема с rm-ом: он выполняется до автоматического redo sync-а. Руками вставить sync до rm -- гарантированно сбросит содержимое PNG, но не гарантирует что файл .png будет создан переименованием. Можно сделать промежуточную .do цель, которая заставит снача��а сделаться (redo-ifchange) .png, а потом удалит .bmp оригинальный. Но по хорошему я бы просто ничего не удалял во время работы -- а подчистил после отработки всего и вся. parallel, sync, rm *.bmp. redo будет медленнее Make для этой задачи, так как 1) на диске хранит состояние целей и зависимостей, 2) делает sync (ok, можно отключить зачастую) и переименования файлов.
Сгенерирован: SGBlog 0.34.0