我使用过一些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:
正如mklement0所指出的,GNU-make中缺少列出所有Makefile目标的功能,他的回答和其他回答提供了实现这一点的方法。
然而,最初的帖子也提到了rake,它的任务开关做的事情与仅仅在rakefile中列出所有任务略有不同。Rake只会给您一个有相关描述的任务列表。没有描述的任务将不会被列出。这使得作者既可以提供定制的帮助描述,也可以省略某些目标的帮助。
如果您想模拟rake的行为,为每个目标提供描述,有一个简单的技术可以做到这一点:在注释中嵌入您想列出的每个目标的描述。
你可以把描述放在目标旁边,或者像我经常做的那样,放在目标上面的PHONY规范旁边,就像这样:
.PHONY: target1 # Target 1 help text
target1: deps
[... target 1 build commands]
.PHONY: target2 # Target 2 help text
target2:
[... target 2 build commands]
...
.PHONY: help # Generate list of targets with descriptions
help:
@grep '^.PHONY: .* #' Makefile | sed 's/\.PHONY: \(.*\) # \(.*\)/\1 \2/' | expand -t20
它会屈服
$ make help
target1 Target 1 help text
target2 Target 2 help text
...
help Generate list of targets with descriptions
你也可以在这里找到一个简短的代码示例。
同样,这不能解决在Makefile中列出所有目标的问题。例如,如果您有一个大的Makefile,它可能是生成的或由其他人编写的,并且您想要一种快速的方法来列出它的目标,而不需要深入研究它,那么这将没有帮助。
但是,如果您正在编写Makefile,并且希望以一致的、自记录的方式生成帮助文本,则此技术可能会有用。
我把上面提到的几个答案编译成这个,它也可以为每个目标生成一个很好的描述,它也适用于有变量的目标。
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:开头的最后一行,用于目标的描述。或者一个空字符串被打印在一个格式化好的表格中。
正如你所看到的,变量甚至在描述中进行了扩展,这在我的书中是一个巨大的奖励:)。
我把这两个答案结合起来: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
正如mklement0所指出的,GNU-make中缺少列出所有Makefile目标的功能,他的回答和其他回答提供了实现这一点的方法。
然而,最初的帖子也提到了rake,它的任务开关做的事情与仅仅在rakefile中列出所有任务略有不同。Rake只会给您一个有相关描述的任务列表。没有描述的任务将不会被列出。这使得作者既可以提供定制的帮助描述,也可以省略某些目标的帮助。
如果您想模拟rake的行为,为每个目标提供描述,有一个简单的技术可以做到这一点:在注释中嵌入您想列出的每个目标的描述。
你可以把描述放在目标旁边,或者像我经常做的那样,放在目标上面的PHONY规范旁边,就像这样:
.PHONY: target1 # Target 1 help text
target1: deps
[... target 1 build commands]
.PHONY: target2 # Target 2 help text
target2:
[... target 2 build commands]
...
.PHONY: help # Generate list of targets with descriptions
help:
@grep '^.PHONY: .* #' Makefile | sed 's/\.PHONY: \(.*\) # \(.*\)/\1 \2/' | expand -t20
它会屈服
$ make help
target1 Target 1 help text
target2 Target 2 help text
...
help Generate list of targets with descriptions
你也可以在这里找到一个简短的代码示例。
同样,这不能解决在Makefile中列出所有目标的问题。例如,如果您有一个大的Makefile,它可能是生成的或由其他人编写的,并且您想要一种快速的方法来列出它的目标,而不需要深入研究它,那么这将没有帮助。
但是,如果您正在编写Makefile,并且希望以一致的、自记录的方式生成帮助文本,则此技术可能会有用。