良好的Makefile实践

1. 背景

这篇文章的主要目的是记录一些可以在Makefile中使用的技巧,以便可以为Makefile本身中的每个目标添加文档,并且可以将其作为make目标查看(例如make help)。

在项目中拥有可靠的文档是一件很了不起的事情,而且如果它们不会过时,那就更好了。通常在顶级Readme.md或类似文件中记录每个Make目标。尽管这是迈出的重要第一步,但更新Makefile而不是更新文档是很常见的,因此使它们变得毫无用处。

2. 目标

最终目标是能够根据Makefile中的注释运行以下内容。

# make

Usage:
  make 

Targets:
  help        Display this help
  deps        Check dependencies
  clean       Cleanup the project folders
  build       Build the project
  watch       Watch file changes and build

对于具有很多目标的复杂Makefile,我们也可以将它们组合在一起。

> make

Usage:
  make 

Dependencies
  deps             Check dependencies

Cleanup
  clean            Cleanup the project folders

Building
  build            Build the project
  watch            Watch file changes and build

Helpers
  help             Display this help

让我们继续看看它是如何实现的

要求:
makeawk是唯一的要求。在macOS(BSD)和Linux(GNU)版本上均能工作。

实现
如上面的示例所示,我们可以针对两种不同的情况实现它们。

  • 简单的makefile

对于目标文件很少的Makefile,我们可以列出所有目标文件而没有任何分组。

首先,添加一个帮助目标。

help:  ## Display this help
	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m\033[0m\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf "  \033[36m%-10s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)

然后,使用上述帮助目标中指定的语法添加注释。在此示例中,我们将使用##作为可打印注释的标签。

deps:  ## Check dependencies
	$(info Checking and getting dependencies)

clean: ## Cleanup the project folders
	$(info Cleaning up things)

build: clean deps ## Build the project
	$(info Building the project)

watch: clean deps ## Watch file changes and build
	$(info Watching and building the project)

(可选)将默认目标添加为help,最好在Makefile的顶部

.DEFAULT_GOAL:=help

(可选)调整目标和通过make help输出的注释之间的宽度。

在上述帮助目标中,将数字10替换为您喜欢的字符宽度。

完整的例子:

.DEFAULT_GOAL:=help
SHELL:=/bin/bash

.PHONY: help deps clean build watch

help:  ## Display this help
	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m\033[0m\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf "  \033[36m%-10s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)

deps:  ## Check dependencies
	$(info Checking and getting dependencies)

clean: ## Cleanup the project folders
	$(info Cleaning up things)

build: clean deps ## Build the project
	$(info Building the project)

watch: clean deps ## Watch file changes and build
	$(info Watching and building the project)
  • 分组的Makefile

添加分组与上面的分组非常相似。我们再添加一种注释格式,以区分分组注释和目标注释,并稍微调整帮助目标以适应更改。

添加帮助目标(确保正确复制/转换制表符)

help:  ## Display this help
	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf "  \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

使用上述帮助目标中指定的语法添加注释。在此示例中,我们将使用##作为可打印注释的标记,并使用## @作为分组注释 的标记

##@ Dependencies

deps:  ## Check dependencies
	$(info Checking and getting dependencies)

##@ Cleanup

clean: ## Cleanup the project folders
	$(info Cleaning up things)

##@ Building

build: clean deps ## Build the project
	$(info Building the project)

watch: clean deps ## Watch file changes and build
	$(info Watching and building the project)

(可选)提供默认目标,并调整目标和打印输出的注释之间的字符宽度,如上面“简单Makefile”部分中所述

完整的例子:

.DEFAULT_GOAL:=help
SHELL:=/bin/bash

##@ Dependencies

.PHONY: deps

deps:  ## Check dependencies
	$(info Checking and getting dependencies)

##@ Cleanup

.PHONY: clean

clean: ## Cleanup the project folders
	$(info Cleaning up things)

##@ Building

.PHONY: build watch

build: clean deps ## Build the project
	$(info Building the project)

watch: clean deps ## Watch file changes and build
	$(info Watching and building the project)

##@ Helpers

.PHONY: help

help:  ## Display this help
	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf "  \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

参考:
make help - Well documented Makefiles
Gist by prwhite
Client9 - Self documenting makefiles
Marmelab - Self documented makefiles

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页