我使用过一些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:开头的最后一行,用于目标的描述。或者一个空字符串被打印在一个格式化好的表格中。

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

其他回答

我最喜欢的答案是Chris Down在Unix & Linux Stack Exchange上发布的。我将引用。

这是make的bash完成模块获取列表的方式: 使得qp | awk - f ': ' ' / ^ [a-zA-Z0-9] [^ $ # \ / \ t =]*:([^=]|$)/ { 分(1美元,/ /);(我的)打印一个[我]}’ 它输出以换行符分隔的目标列表,不进行分页。

用户Brainstone建议使用sort -u来删除重复的条目:

make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}' | sort -u

来源:如何列出所有的目标在使?(unix和linux SE)

非常简单的AWK解决方案:

all:
    @awk -F'[ :]' '!/^all:/ && /^([A-z_-]+):/ {print "make " $$1}' Makefile

(注:这并没有涵盖所有被接受的极端情况,如这里解释的那样。)

要扩展@jsp给出的答案,甚至可以使用$(eval)函数计算帮助文本中的变量。

下面提议的版本增强了以下属性:

将扫描任何生成文件(甚至包括在内) 是否会在帮助注释中引用扩展活动变量 为真实目标添加文档锚(前缀为# TARGETDOC:) 添加列标头

所以要记录,请使用这种形式:

RANDOM_VARIABLE := this will be expanded in help text

.PHONY: target1 # Target 1 help with $(RANDOM_VARIABLE)
target1: deps
    [... target 1 build commands]

# TARGETDOC: $(BUILDDIR)/real-file.txt # real-file.txt help text
$(BUILDDIR)/real-file.txt:
    [... $(BUILDDIR)/real-file.txt build commands]

然后,在你的makefile文件的某处:

.PHONY: help # Generate list of targets with descriptions
help:
    @# find all help in targets and .PHONY and evaluate the embedded variables
    $(eval doc_expanded := $(shell grep -E -h '^(.PHONY:|# TARGETDOC:) .* #' $(MAKEFILE_LIST) | sed -E -n 's/(\.PHONY|# TARGETDOC): (.*) # (.*)/\2  \3\\n/'p | expand -t40))
    @echo
    @echo ' TARGET   HELP' | expand -t40
    @echo ' ------   ----' | expand -t40
    @echo -e ' $(doc_expanded)'

如果为make安装了bash补全,补全脚本将定义一个函数_make_target_extract_script。该函数用于创建一个sed脚本,该脚本可用于以列表的形式获取目标。

像这样使用它:

# Make sure bash completion is enabled
source /etc/bash_completion 

# List targets from Makefile
sed -nrf <(_make_target_extract_script --) Makefile

这里有很多可行的解决方案,但正如我喜欢说的,“如果值得做一次,就值得再做一次。” 我确实赞成使用(tab)(tab)的建议,但正如一些人指出的那样,您可能没有补全支持,或者,如果您有许多包含文件,您可能想要一种更简单的方法来知道目标定义在哪里。

我还没有测试下面的子制作…我认为这行不通。我们知道,递归是有害的。

.PHONY: list ls
ls list :
    @# search all include files for targets.
    @# ... excluding special targets, and output dynamic rule definitions unresolved.
    @for inc in $(MAKEFILE_LIST); do \
    echo ' =' $$inc '= '; \
    grep -Eo '^[^\.#[:blank:]]+.*:.*' $$inc | grep -v ':=' | \
    cut -f 1 | sort | sed 's/.*/  &/' | sed -n 's/:.*$$//p' | \
    tr $$ \\\ | tr $(open_paren) % | tr $(close_paren) % \
; done

# to get around escaping limitations:
open_paren := \(
close_paren := \)

我喜欢它是因为:

通过包含文件列出目标。 输出原始动态目标定义(用模替换变量分隔符) 在新行上输出每个目标 似乎更清楚了(主观意见)

解释:

MAKEFILE_LIST中的foreach文件 输出文件的名称 包含冒号的Grep行,不缩进,没有注释,也不以句号开头 排除立即赋值表达式(:=) 切、排序、缩进和切规则依赖项(冒号后) 蒙格变量分隔符以防止扩展

样例输出:

 = Makefile = 
  includes
  ls list
 = util/kiss/snapshots.mk = 
  rotate-db-snapshots
  rotate-file-snapshots
  snap-db
  snap-files
  snapshot
 = util/kiss/main.mk = 
  dirs
  install
   %MK_DIR_PREFIX%env-config.php
   %MK_DIR_PREFIX%../srdb