如何自动生成Makefile帮助命令

问题描述 投票:0回答:3

我最近在网上找到了这篇文章,它解释了如何设置一个

make help
目标,该目标将自动解析Makefile以获取注释并显示格式良好的帮助命令。

它解析:

install: ## Install npm dependencies for the api, admin, and frontend apps
    @echo "Installing Node dependencies"
    @npm install

install-dev: install ## Install dependencies and prepared development configuration
    @./node_modules/.bin/selenium-standalone install
    @cp -n ./config/development.js-dist ./config/development.js | true

run-frontend-dev: webpack.PID ## Run the frontend and admin apps in dev (using webpack-dev-server)

进入:

install              Install npm dependencies for the api, admin, and frontend apps
install-dev          Install dependencies and prepared development configuration
run-frontend-dev     Run the frontend and admin apps in dev (using webpack-dev-server)

但由于某种原因我无法让它工作(至少在 OSX 上)。有了这个目标:

help: ## Show the help prompt.
  @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

当我跑步时:

make help

我刚刚得到:

$ make help
make: Nothing to be done for `help'.

我也尝试了文章中评论中的所有不同解决方案,但似乎没有任何效果。我做错了什么?

此外,脚本的一个变体是什么,允许将注释放置在目标之前而不是之后的行上。像这样:

# Build the source files with Babel. build: $(shell find lib) @rm -rf build @mkdir -p build @$(babel) lib $(babel_options) # Seed the database with fake data. db-fake: @$(run) node bin/run-sql fake

这是有问题的完整 Makefile:

# Options. DEBUG ?= SOURCEMAPS ?= true WATCH ?= # Variables. bin = ./node_modules/.bin tests = $(shell find test/routes -depth 1) shorthand-tests = $(patsubst test/routes/%.js,test-%,$(tests)) # Binaries. babel = $(bin)/babel mocha = $(bin)/mocha node = node nodemon = $(bin)/nodemon run = heroku local:run # Babel options. babel_options = \ --out-dir build \ --copy-files # Sourcemaps? ifneq ($(SOURCEMAPS),false) babel_options += --source-maps endif # Watch? ifdef WATCH babel_options += --watch endif # Development? ifneq ($(NODE_ENV),production) node = $(nodemon) endif # Debug? ifdef DEBUG node += debug mocha += debug endif # Default. default: help ## Default. # Build the source files with Babel. build: $(shell find lib) ## Build the source files with Babel. @rm -rf build @mkdir -p build @$(babel) lib $(babel_options) # Seed the database with fake data. db-fake: ## Seed the database with fake data. @$(run) node bin/run-sql fake # Reset the database, dropping everything and the creating again. db-reset: ## Reset the database, dropping everything and the creating again. @$(run) node bin/run-sql drop @$(run) node bin/run-sql create # Seed the database with test data. db-seed: ## Seed the database with test data. @$(run) node bin/run-sql seed # Show the help prompt. help: ## Show the help prompt. @awk '/^#/{c=substr($0,3);next}c&&/^[[:alpha:]][[:alnum:]_-]+:/{print substr($1,1,index($1,":")),c}1{c=0}' mm.mk | column -s: -t # Open the PSQL interface. psql: ## Open the PSQL interface. @psql contentshq # Run the development server. server: ## Run the development server. @$(run) $(node) bin/api # Start the local postgres server. start: ## Start the local postgres server. @pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start # Stop the local postgres server. stop: ## Stop the local postgres server. @pg_ctl -D /usr/local/var/postgres stop -s -m fast # Run all of the tests. test: ## Run all of the tests. @$(run) $(mocha) $(tests) # Run specific route tests. $(shorthand-tests): ## Run specific route tests. @$(run) $(mocha) test/routes/$(subst test-,,$@).js # Watch the source files with Babel. watch: ## Watch the source files with Babel. @WATCH=true $(MAKE) build # Phony targets. .PHONY: help .PHONY: test .PHONY: watch
    
macos unix makefile gnu
3个回答
7
投票
这里有一个 awk 小脚本,它将处理注释出现在目标名称之前的情况。我使用

column

 将文本放入列中,但您可以使用 printf 在 awk 中完成此操作(如果您愿意,还可以添加控制台代码来对输出进行着色);使用 
column
 的优点是它会自动计算出列宽。

您可以用同样的方式将其插入到 Makefile 中:

.PHONY: help # Show this help. help: @awk '/^#/{c=substr($$0,3);next}c&&/^[[:alpha:]][[:alnum:]_-]+:/{print substr($$1,1,index($$1,":")),c}1{c=0}' $(MAKEFILE_LIST) | column -s: -t
    

4
投票
您需要一个

help

 规则来实际提取和打印消息。假设您正在谈论的文章是 
http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html,这就是您正在寻找的内容。

.PHONY: help help: @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

命令方法之前的文档可能是可行的,但需要更多的工作。大多数 UNIX 命令都是逐行工作的,因此使用本文中指定的注释会更容易。


0
投票
我喜欢

risi的答案,并对它做了一些改进。通过此更改,Makefile 中以 ## 开头的任何注释都将传递到帮助文本中,而 make 目标之前的 ## 注释将呈现为该目标的帮助。

# this line does not go into help ## ## This is the help header 1 ## This is the help header 2 ## # The above line is ##<SPACE><SPACE> which inserts a line break .PHONEY: help ## Print this help help: @awk '/^## / \ { if (c) {print c}; c=substr($$0, 4); next } \ c && /^[[:alpha:]][[:alnum:]_0]+:/ \ {print substr($$0, 1, index($$0,":")), "\t", c; c=0} \ END { print c }' $(MAKEFILE_LIST) # This target will not appear in help target0: @action 0 ## Description 1 target1: @action 1 ## Description 2 target2: target1 @action 2 ## ## This can be a description of another subsection ## ## Description 3 target3: @action 3 ## ## Some text to finish up the help. ##
在此 Makefile 上运行“make help”将生成:

This is the help header 1 This is the help header 2 help: Print this help target1: Description 1 target2: Description 2 This can be a description of another subsection target3: Description 3 Some text to finish up the help.
无法像 Risi 的解决方案一样使用“列”,因为它会干扰与目标无关的帮助输出。

© www.soinside.com 2019 - 2024. All rights reserved.