unix 如何自动生成Makefile帮助命令

vc6uscn9  于 2023-10-18  发布在  Unix
关注(0)|答案(3)|浏览(152)

我最近发现了this article online,它解释了如何设置一个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
fzsnzjdm

fzsnzjdm1#

这里有一个小awk脚本,它将处理注解位于目标名称之前的情况。我使用column将文本放入列中,但您也可以在awk中使用printf(如果需要,还可以添加控制台代码以着色输出);使用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
epfja78i

epfja78i2#

您需要一个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命令都是逐行工作的,因此使用本文中指定的注解会更容易。

xxe27gdn

xxe27gdn3#

我喜欢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:]_-]+:)/ \
        {print $$1, "\t", c; c=0} \
         END { print c }' $(MAKEFILE_LIST)

# This target will not appear in help
target0:
    @echo action 0

## Description 1
target1:
    @echo action 1

## Description 2
target2: target1
    @echo action 2

##
## This can be a description of another subsection
##

## Description 3
target3:
    @echo 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的解决方案那样使用“列”,因为它会干扰与目标无关的帮助输出。

相关问题