Make в 21-вом веке
Все современные фреймворки и языки программирования обладают отличной экосистемой: cargo
у языка rust
; manage.py
у фреймворка django
; go
нужна только одна команда. Все это избавляет от необходимости использовать сторонние тулзы. Но есть инструмент от которого я не могу отказаться - make
. Созданный еще в 70-х как инструмент сборки, он до сих пор остается чрезвычайно полезным инструментом в любом проекте.
Краткое введение
Все что нужно для запуска make
это файл Makefile
. В нем описываются правила по шаблону:
target: prerequisites
recipe
Где:
target
- это имя файла;prerequisites
- это набор правил которые будут исполнены до запуска текущего правила;recipe
- набор команд для выполнения;
Следуя этим правилам make
будет собирать что-то, если это нужно собирать. По умолчанию target
является именем файла, который будет создан по окончанию выполнения блока recipe
. make
отслеживает prerequisites
, если они были изменены с последнего запуска, то target
будет заново собрана, а иначе make
не предпринимает ни каких действий.
Рассмотрим простой пример Makefile
:
foo: bar
echo "foo" > foo
bar:
echo "bar" > bar
Если просто запустить make
, он выполнит первое правило из возможных т.е. foo
.
$ make
echo "bar" > bar
echo "foo" > foo
Но так как правило имеет предпосылки, то сначала будет выполнено правило bar
, а лишь затем foo
.
Если запустить make
еще раз, то программа сообщает, что файлы bar
и foo
уже созданы и делать ничего не нужно.
Если нужно выполнить определенное правило, то при запуске нужно указать имя.
$ make bar
Синтаксис Makefile
очень богат. Позволяет создавать переменные:
MY_FILE := foo
$(MY_FILE):
echo "foo" > $(MY_FILE)
Помечать правила по результатам которых не создается файла, это особенно полезно при запуске тестов или линтеров:
.PHONY: foo
foo:
echo "foo"
Указывать правило по-умоланию:
.DEFAULT_GOAL := foo
.PHONY: foo
foo:
echo "foo"
И еще много чего.
Зачем мне make?
Возьмем go
, любой разработчик на этом языке может сказать “Зачем мне make? Тесты я могу запускать go test
, устанавливать через go install
и тд “.
В данном случае make
нужно рассматривать как инструмент оптимизации временных затрат. Предположим нужно собрать версию приложения для linux, а вы работаете на macos, очень утомительно писать каждый раз: GOOS=linux GOARCH=amd64 go build -o builds/app-linux-amd64
. А если нужно собрать приложение сразу под все платформы? Согласитесь make release
выглядит более продуктивно.
Кроме того, не стоит забывать, что Makefile
это отличный инструмент для документирования. В нем может быть описано как запускать тесты, как собирать приложение, какие оптимизации сборки были выполнены. Запустить проект будет возможно даже если документация к нему была утеряна.
Заключение
Хотя make при знакомстве может показаться архаичным и не нужным инструментом в современных экосистемах. Не стоит его клеймить и выбрасывать, возможно он поможет вам оптимизировать рутинные задачи.