Bri*_*rns 176 makefile gnu-make targets
我已经使用了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...
...
Run Code Online (Sandbox Code Playgroud)
但似乎没有选择在GNU make中执行此操作.
显然,代码几乎就在那里,截至2007年 - http://www.mail-archive.com/help-make@gnu.org/msg06434.html.
无论如何,我几乎没有从makefile中提取目标,你可以将其包含在makefile中.
list:
@grep '^[^#[:space:]].*:' Makefile
Run Code Online (Sandbox Code Playgroud)
它将为您提供已定义目标的列表.这只是一个开始 - 例如,它不会过滤掉依赖项.
> make list
list:
copy:
run:
plot:
turnin:
Run Code Online (Sandbox Code Playgroud)
nob*_*bar 167
在Bash(至少)下,这可以通过选项卡完成自动完成:
__PRE__
mkl*_*nt0 107
这是尝试改进@ nobar的伟大方法,如下所示:
sh -c)-f <file>@以防止在执行前回显它奇怪的是,GNU make没有列出makefile中定义的目标名称的功能.该-p选项生成包含所有目标的输出,但将其隐藏在许多其他信息中.
将以下规则放在GNU的makefile中,make以实现一个名为的目标list,该目标只是按字母顺序列出所有目标名称 - 即:调用asmake list:
.PHONY: list
list:
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
Run Code Online (Sandbox Code Playgroud)
重要说明:粘贴此内容时,请确保最后一行缩进1个实际的tab char.(空格也没有工作).
请注意,对结果目标列表进行排序是最佳选择,因为不排序不会产生有用的排序,因为不保留目标在makefile中出现的顺序.
此外,包含多个目标的规则的子目标总是单独输出,因此,由于分类,通常不会彼此相邻; 例如,如果有其他目标,则开头的规则a z:将没有目标a并且在输出中彼此相邻z列出.
规则说明:
PHONY: list
$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null
make再次调用以打印和解析从makefile派生的数据库:
-p 打印数据库-Rr 禁止包含内置规则和变量-q只测试目标的最新状态(不重新编译任何东西),但这本身并不妨碍在所有情况下执行配方命令; 因此:-f $(lastword $(MAKEFILE_LIST))确保与原始调用中的目标相同的makefile,无论是隐式还是显式定位-f ....include指令,这将会中断; 要解决这个问题,请THIS_FILE := $(lastword $(MAKEFILE_LIST)) 在任何include指令之前定义变量并使用-f $(THIS_FILE).:是故意无效的目标,旨在确保不执行任何命令 ; 2>/dev/null抑制产生的错误消息.注意:这依赖于-p打印数据库,就像GNU make 3.82一样.可悲的是,GNU要约没有直接的选项,只是打印数据库,不还执行默认(或给出)任务; 如果您不需要定位特定的Makefile,您可以make -p -f/dev/null按照man页面中的建议使用.-v RS=
/^# File/,/^# Finished Make data base/
if ($$1 !~ "^[#.]")
# ...忽略其块开头的非目标 # Not a target:. ...忽略特殊目标 :egrep -v -e '^[^[:alnum:]]' -e '^$@$$' 从输出中删除不需要的目标:
'^[^[:alnum:]]'......排除隐藏的目标,按照惯例,这些目标既不是字母也不是数字.'^$@$$'......排除list目标本身make list
nob*_*bar 25
我将这两个答案结合起来:https://stackoverflow.com/a/9524878/86967和/sf/answers/517361211/ 并进行了一些转义,以便可以在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"
Run Code Online (Sandbox Code Playgroud)
.
$ make -s list
build
clean
default
distclean
doc
fresh
install
list
makefile ## this is kind of extraneous, but whatever...
run
Run Code Online (Sandbox Code Playgroud)
Tim*_*mmm 22
这在很多情况下显然不起作用,但如果你Makefile是由CMake创建的,那么你可以运行make help.
$ make help
The following are some of the valid targets for this Makefile:
... all (the default if no target is provided)
... clean
... depend
... install
etc
Run Code Online (Sandbox Code Playgroud)
hek*_*mgl 13
如果已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
Run Code Online (Sandbox Code Playgroud)
Mar*_*377 12
我最喜欢的答案是Chris Down在 Unix & Linux Stack Exchange 上发表的。我来报价。
这是 bash 完成模块
make获取其列表的方式:Run Code Online (Sandbox Code Playgroud)make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}'它打印出以换行符分隔的目标列表,无需分页。
用户Brainstone建议通过管道sort -u删除重复条目:
make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}' | sort -u
Run Code Online (Sandbox Code Playgroud)
来源:如何列出 make 中的所有目标?(Unix&Linux SE)
jsp*_*jsp 11
正如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
Run Code Online (Sandbox Code Playgroud)
哪个会产生
$ make help
target1 Target 1 help text
target2 Target 2 help text
...
help Generate list of targets with descriptions
Run Code Online (Sandbox Code Playgroud)
同样,这并没有解决在Makefile中列出所有目标的问题.例如,如果你有一个可能生成的大型Makefile或其他人写的,你想要一个快速的方法来列出它的目标而不需要深入研究它,这将无济于事.
但是,如果您正在编写Makefile,并且希望以一致的自我文档方式生成帮助文本,则此技术可能很有用.
ron*_*akg 10
我采用了上面提到的一些答案并编译了这个答案,它还可以为每个目标生成一个很好的描述,并且它也适用于带有变量的目标。
示例生成文件:
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"'
Run Code Online (Sandbox Code Playgroud)
输出示例:
$ 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
Run Code Online (Sandbox Code Playgroud)
它是如何工作的:
目标的顶部部分的make help工作方式与 mklement0 此处发布的完全相同 - How do you get the list of Targets in a makefile? 。
获取目标列表后,它会make <target> -nB为每个目标运行试运行,并解析以@# Help:目标描述开头的最后一行。并且该字符串或空字符串会打印在格式良好的表格中。
正如您所看到的,变量甚至在描述中也得到了扩展,这对我的书中来说是一个巨大的好处:)。
专注于描述 make 目标的简单语法和干净的输出,我选择了这种方法:
help:
@grep -B1 -E "^[a-zA-Z0-9_-]+\:([^\=]|$$)" Makefile \
| grep -v -- -- \
| sed 'N;s/\n/###/' \
| sed -n 's/^#: \(.*\)###\(.*\):.*/\2###\1/p' \
| column -t -s '###'
#: Starts the container stack
up: a b
command
#: Pulls in new container images
pull: c d
another command
make-target-not-shown:
# this does not count as a description, so leaving
# your implementation comments alone, e.g TODOs
also-not-shown:
Run Code Online (Sandbox Code Playgroud)
因此,将上述内容视为 Makefile 并运行它会给您类似的结果
> make help
up Starts the container stack
pull Pulls in new container images
Run Code Online (Sandbox Code Playgroud)
命令链说明:
这是一种非常简单的方法,基于上面bash@cibercitizen1 的评论:
grep : Makefile | awk -F: '/^[^.]/ {print $1;}'
Run Code Online (Sandbox Code Playgroud)
另请参阅@Marc.2377 的更权威的答案,其中说明了 Bash 补全模块是如何make做到这一点的。
将此目标添加到您的 Makefile 中:
help:
@echo "\nTARGETS:\n"
@make -qpRr | egrep -e '^[a-z].*:$$' | sed -e 's~:~~g' | sort
@echo ""
Run Code Online (Sandbox Code Playgroud)
make -qpRr=make --question --print-data-base --no-builtin-variables --no-builtin-rulesegrep -e '^[a-z].*:$$':搜索以小写字母开头并以“:”结尾的行sed -e 's~:~~g': 删除“:”然后运行:
make help
Run Code Online (Sandbox Code Playgroud)
这对我有用
PD:更多信息请访问...
make --help
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
115121 次 |
| 最近记录: |