我使用过一些rake(一个Ruby make程序),它有一个选项,可以获得所有可用目标的列表,例如

> rake --tasks
rake db:charset      # retrieve the charset for your data...
rake db:collation    # retrieve the collation for your da...
rake db:create       # Creates the databases defined in y...
rake db:drop         # Drops the database for your curren...
...

但是在GNU make中似乎没有这样做的选项。

显然,代码几乎已经有了,截至2007年- http://www.mail-archive.com/help-make@gnu.org/msg06434.html。

不管怎样,我做了一个小hack来从makefile中提取目标,你可以将它包含在makefile中。

list:
    @grep '^[^#[:space:]].*:' Makefile

它会给你一个已定义目标的列表。这只是一个开始——例如,它并没有过滤掉依赖关系。

> make list
list:
copy:
run:
plot:
turnin:

当前回答

我把上面提到的几个答案编译成这个,它也可以为每个目标生成一个很好的描述,它也适用于有变量的目标。

Makefile示例:

APPS?=app1 app2

bin: $(APPS:%=%.bin)
    @# Help: A composite target that relies only on other targets

$(APPS:%=%.bin): %.bin:
    @# Help: A target with variable name, value = $*

test:
    @# Help: A normal target without variables

# A target without any help description
clean:

# A hidden target
.hidden:

help:
    @printf "%-20s %s\n" "Target" "Description"
    @printf "%-20s %s\n" "------" "-----------"
    @make -pqR : 2>/dev/null \
        | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' \
        | sort \
        | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' \
        | xargs -I _ sh -c 'printf "%-20s " _; make _ -nB | (grep -i "^# Help:" || echo "") | tail -1 | sed "s/^# Help: //g"'

示例输出:

$ make help
Target               Description
------               -----------
app1.bin             A target with variable name, value = app1
app2.bin             A target with variable name, value = app2
bin                  A composite target that relies only on other targets
clean
test                 A normal target without variables

它是如何工作的:

make help目标的顶部部分与mklement0在这里发布的工作完全相同——如何在makefile中获得目标列表?

在获得目标列表之后,它运行make <target> -nB作为每个目标的演练,并解析以@# Help:开头的最后一行,用于目标的描述。或者一个空字符串被打印在一个格式化好的表格中。

正如你所看到的,变量甚至在描述中进行了扩展,这在我的书中是一个巨大的奖励:)。

其他回答

在Bash下(至少),这可以通过制表符自动完成:

可我会spacetabtab

这是对jsp非常有用的回答(https://stackoverflow.com/a/45843594/814145)的修改。我喜欢这个想法,不仅要得到目标的列表,还要得到他们的描述。jsp的Makefile将描述作为注释,我发现在目标的描述echo命令中经常会重复。因此,我从每个目标的echo命令中提取描述。

Makefile示例:

.PHONY: all
all: build
    : "same as 'make build'"

.PHONY: build
build:
    @echo "Build the project"

.PHONY: clean
clean:
    @echo "Clean the project"

.PHONY: help
help:
    @echo -n "Common make targets"
    @echo ":"
    @cat Makefile | sed -n '/^\.PHONY: / h; /\(^\t@*echo\|^\t:\)/ {H; x; /PHONY/ s/.PHONY: \(.*\)\n.*"\(.*\)"/    make \1\t\2/p; d; x}'| sort -k2,2 |expand -t 20

make help输出:

$ make help
Common make targets:
    make all        same as 'make build'
    make build      Build the project
    make clean      Clean the project
    make help       Common make targets

注:

与jsp的答案相同,只能列出PHONY目标,这可能适用于您的情况,也可能不适用 此外,它只列出那些有echo或:命令作为recipe的第一个命令的PHONY目标。:表示“什么都不做”。我在这里将它用于那些不需要回声的目标,比如上面所有的目标。 帮助目标还有一个额外的技巧,就是在make帮助输出中添加“:”。

我把这两个答案结合起来:https://stackoverflow.com/a/9524878/86967和https://stackoverflow.com/a/7390874/86967 并做了一些转义,以便可以从makefile中使用。

.PHONY: no_targets__ list
no_targets__:
list:
    sh -c "$(MAKE) -p no_targets__ | awk -F':' '/^[a-zA-Z0-9][^\$$#\/\\t=]*:([^=]|$$)/ {split(\$$1,A,/ /);for(i in A)print A[i]}' | grep -v '__\$$' | sort"

.

$ make -s list
build
clean
default
distclean
doc
fresh
install
list
makefile ## this is kind of extraneous, but whatever...
run

这是对上述问题的另一个回答。

在MacOSX上测试,终端只使用cat和awk

cat Makefile | awk '!/SHELL/ && /^[A-z]/ {print $1}' | awk '{print substr($0, 1, length($0)-1)}'

将像下面这样输出make文件:

target1 target2 target3

在Makefile中,它应该是相同的语句,确保使用$$variable而不是$variable来转义变量。

解释

猫吐出里面的东西

| -管道解析输出到下一个awk

awk -运行正则表达式,排除“shell”,只接受“A-z”行,然后打印出$1第一列

Awk—再次从列表中删除最后一个字符“:”

这是一个粗略的输出,你可以用AWK做更多有趣的事情。尽量避免sed,因为它在bsd变体中不一致,即一些在*nix上工作,但在MacOSX等bsd上失败。

More

您应该能够将此(经过修改)添加到make的文件中,添加到默认的bash-completion文件夹/usr/local/etc/bash-completion.d/ 意思是当你“使标签标签”..它将基于一行脚本完成目标。

我把上面提到的几个答案编译成这个,它也可以为每个目标生成一个很好的描述,它也适用于有变量的目标。

Makefile示例:

APPS?=app1 app2

bin: $(APPS:%=%.bin)
    @# Help: A composite target that relies only on other targets

$(APPS:%=%.bin): %.bin:
    @# Help: A target with variable name, value = $*

test:
    @# Help: A normal target without variables

# A target without any help description
clean:

# A hidden target
.hidden:

help:
    @printf "%-20s %s\n" "Target" "Description"
    @printf "%-20s %s\n" "------" "-----------"
    @make -pqR : 2>/dev/null \
        | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' \
        | sort \
        | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' \
        | xargs -I _ sh -c 'printf "%-20s " _; make _ -nB | (grep -i "^# Help:" || echo "") | tail -1 | sed "s/^# Help: //g"'

示例输出:

$ make help
Target               Description
------               -----------
app1.bin             A target with variable name, value = app1
app2.bin             A target with variable name, value = app2
bin                  A composite target that relies only on other targets
clean
test                 A normal target without variables

它是如何工作的:

make help目标的顶部部分与mklement0在这里发布的工作完全相同——如何在makefile中获得目标列表?

在获得目标列表之后,它运行make <target> -nB作为每个目标的演练,并解析以@# Help:开头的最后一行,用于目标的描述。或者一个空字符串被打印在一个格式化好的表格中。

正如你所看到的,变量甚至在描述中进行了扩展,这在我的书中是一个巨大的奖励:)。