Прокачай мой Makefile

Чтобы не повторяться, рекомендуется поместить все задачи, которые вы можете выполнить дважды, где-нибудь в своем проекте. Makefile — идеальное место, а также исполняемая документация: вместо документирования процесса сборки вы должны записать его в цель сборки



Make почти везде — либо установлен, либо на расстоянии одной команды во всех дистрибутивах Linux. Но он далек от совершенства: например, нет встроенной справки или какой-либо опции для перечисления доступных целей для выполнения завершения Bash.

Помощь по целям

Рассмотрим следующий Makefile:

BUILD_DIR=build

clean: # Clean generated files and test cache
	@rm -rf $(BUILD_DIR)
	@go clean -testcache

fmt: # Format Go source code
	@go fmt ./...

test: clean # Run unit tests
	@go test -cover ./...

.PHONY: build
build: clean # Build binary
	@mkdir -p $(BUILD_DIR)
	@go build -ldflags "-s -f" -o $(BUILD_DIR)/hello .


В приведенном выше примере Make не предоставляет возможность перечислить доступные цели или документацию, извлеченную из комментариев. Давай сделаем это:

BUILD_DIR=build

help: # Print help on Makefile
	@grep '^[^.#]\+:\s\+.*#' Makefile | \
	sed "s/\(.\+\):\s*\(.*\) #\s*\(.*\)/`printf "\033[93m"`\1`printf "\033[0m"`	\3 [\2]/" | \
	expand -t20

clean: # Clean generated files and test cache
	@rm -rf $(BUILD_DIR)
	@go clean -testcache

fmt: # Format Go source code
	@go fmt ./...

test: clean # Run unit tests
	@go test -cover ./...

.PHONY: build
build: clean # Build binary
	@mkdir -p $(BUILD_DIR)
	@go build -ldflags "-s -f" -o $(BUILD_DIR)/hello .


Теперь вы можете создавать справку по целям, набрав:

$ make help
help       Print help on Makefile []
clean      Clean generated files and test cache []
fmt        Format Go source code []
test       Run unit tests [clean]
build      Build binary [clean]


Target help анализирует Makefile с помощью регулярного выражения, чтобы извлечь целевые имена, описания и зависимости, чтобы распечатать их на терминале. Поскольку эта цель является первой в Makefile, она используется по умолчанию, и вы можете получить помощь, набрав make .

Завершение удара по целям

Некоторые дистрибутивы предоставляют пакет для добавления завершения Bash в цели Make, другие — нет. Если у вас нет завершения при вводе make [TAB] , вы можете добавить его, используя следующий файл (например, в вашем файле ~ / .bashrc ):

# /etc/profile.d/make

complete -W "\`grep -oEs '^[a-zA-Z0-9_-]+:([^=]|$)' ?akefile | sed 's/[^a-zA-Z0-9_.-]*$//'\`" make


В примере файла сборки завершение будет напечатано:

$ make [TAB]
build  clean  fmt    help   test
$ make t[TAB]est


Это удобно для больших Make-файлов с несколькими целями.

Включение Makefile

Можно включить дополнительные файлы Makefile, которые включают директивы. Одним из примеров этого может быть включение Makefile help.mk в тот же каталог:

help: # Print help on Makefile
	@grep '^[^.#]\+:\s\+.*#' Makefile | \
	sed "s/\(.\+\):\s*\(.*\) #\s*\(.*\)/`printf "\033[93m"`\1`printf "\033[0m"`	\3 [\2]/" | \
	expand -t20


Его можно импортировать в основной Makefile следующим образом:

include help.mk

BUILD_DIR=build

clean: # Clean generated files and test cache
	@rm -rf $(BUILD_DIR)
	@go clean -testcache

fmt: # Format Go source code
	@go fmt ./...

test: clean # Run unit tests
	@go test -cover ./...

.PHONY: build
build: # Build binary
	@mkdir -p $(BUILD_DIR)
	@go build -ldflags "-s -f" -o $(BUILD_DIR)/hello .


Это будет включать в себя help.mk с целевой помощью. Но поскольку целевой справки больше нет в основном файле Makefile, она больше не будет отображаться при печати справки:

$ make help

$ make help
clean      Clean generated files and test cache []
fmt        Format Go source code []
test       Run unit tests [clean]
build      Build binary [clean]


По той же причине завершение Bash не будет включать целевую справку. Включение справки и завершения во включенных Make-файлах требует дополнительной работы для их анализа и учета включенных целей.

Сделать инструменты

Make Tools используются для решения этих проблем с включением. Таких инструментов два:

Сделайте помощь
Инструмент Make Help сканирует текущий каталог в поисках make-файла, а затем анализирует его, чтобы извлечь информацию о целях. Включенные make-файлы анализируются рекурсивно. Таким образом, чтобы распечатать справку в предыдущем примере, вы должны ввести:

$ make-help
build Build binary [clean]
clean Clean generated files and test cache
fmt   Format Go source code
help  Print help on Makefile
test  Run unit tests [clean]


Мы знаем, что цели отсортированы и что цель справки включена в печатную справку.

Вы можете включить эту цель справки в make-файл со следующим определением:

.PHONY: help
help: # Print help on Makefile
	@make-help


Сделать цели
Этот инструмент рекурсивно перечисляет цели make-файла в текущем каталоге и все включенные. В предыдущем примере:

$ make-targets
build clean fmt help test


Таким образом, чтобы выполнить завершение bash, вы должны указать:

# /etc/profile.d/make

complete -W "\`make-targets\`" make


Известные ошибки
Эти инструменты работают так же, как и make:

  • Включенные файлы относятся к текущему каталогу, а не к соответствующему make-файлу.
  • Для включений нет бесконечного цикла обнаружения.

Этот инструмент с открытым исходным кодом, не стесняйтесь вносить свой вклад и улучшать его.

Наслаждайтесь!

0 комментариев

Оставить комментарий