Bit*_*ter 99 makefile gnu-make
我有一个相当大的makefile,它通过计算变量中的名称来动态创建多个目标.(例如foo $(VAR):$(PREREQS)).有没有什么方法可以让gnu make在扩展这些变量之后吐出一系列目标?
我希望能够获得aribitrary makefile的目标.我正在尝试为我的shell编写一个完成函数.
小智 113
make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}'
Run Code Online (Sandbox Code Playgroud)
取自make arg完成,其作品就像一个魅力.
Jac*_*lly 78
你能解析make -pn(即make --print-data-base --dry-run)的输出吗?它打印出所有变量,规则,隐式规则以及哪些命令将以繁重的细节运行.
Zde*_*nik 13
我不确定这只是一个gnu make的东西,但这很有效:
make help
Eri*_*ski 10
一些响应者建议使用make -pn,它将打印规则数据库但不执行任何操作 - 或多或少.这种方法的问题在于-n仍然会调用所有递归的make,并且它仍然会执行比必要更多的工作,因为它会打印出它在常规构建中调用的每个命令.更有效的解决方案是使用以下内容创建一个简单的makefile,dummy.mk:
__all_targets__: ; #no-op
Run Code Online (Sandbox Code Playgroud)
现在调用make as make -p -f Makefile -f dummy.mk __all_targets__.在任何实质性构建中,make产生的输出量的差异是显着的.例如:
$ gmake -pn | wc
138985 2632330 69612711
$ gmake -f Makefile -f /tmp/dummy.mk -pn __all_targets__ | wc
21673 93437 878985
Run Code Online (Sandbox Code Playgroud)
执行时间也明显更好 - 第一个版本为2.063秒,第二个版本为0.059秒.
编辑:仅供参考,在另一个答案中,debian bash完成git存储库现在包含了为bash完成用例量身定制的此脚本的增强版本.
#!/bin/bash
SCRIPT='
/^# Make data base/,/^# Files/d # skip until files section
/^# Not a target/,+1 d # following target isnt
/^\.PHONY:/ d # special target
/^\.SUFFIXES:/ d # special target
/^\.DEFAULT:/ d # special target
/^\.PRECIOUS:/ d # special target
/^\.INTERMEDIATE:/ d # special target
/^\.SECONDARY:/ d # special target
/^\.SECONDEXPANSION/ d # special target
/^\.DELETE_ON_ERROR:/ d # special target
/^\.IGNORE:/ d # special target
/^\.LOW_RESOLUTION_TIME:/ d # special target
/^\.SILENT:/ d # special target
/^\.EXPORT_ALL_VARIABLES:/ d # special target
/^\.NOTPARALLEL:/ d # special target
/^\.ONESHELL:/ d # special target
/^\.POSIX:/ d # special target
/^\.NOEXPORT:/ d # special target
/^\.MAKE:/ d # special target
# The stuff above here describes lines that are not
# explicit targets or not targets other than special ones
# The stuff below here decides whether an explicit target
# should be output.
/^[^#\t:=%]+:([^=]|$)/ { # found target block
h # hold target
d # delete line
}
/^# File is an intermediate prerequisite/ { # nope
s/^.*$//;x # unhold target
d # delete line
}
/^([^#]|$)/ { # end of target block
s/^.*$//;x # unhold target
s/:.*$//p # write current target
d # hide any bugs
}
'
make -npq .DEFAULT 2>/dev/null | sed -n -r "$SCRIPT" \
| sort | uniq
Run Code Online (Sandbox Code Playgroud)
这是一个比debian bash完成脚本更完整的脚本,因为它提供了生成规则的结果,问题要求和最高投票答案(debian git服务器上的debian bash完成脚本)还不够.
这不是我链接到的原始脚本,但它更简单,触摸速度更快.