有没有办法在 a 中标记某些目标,以便当用户键入然后按 时Makefile
它们根本不会出现在 shell 中?我有太多的食谱,当用户按下寻找目标时,我不希望它们全部出现在 shell 自动完成中。make
Tab
Makefile
Tab
答案1
在研究了这个问题并提出了我在第一个答案中写的解决方案之后,我意识到还有另一个很简单方式。
只需以您不想显示的目标名称开头点。
例子:
.PHONY: foo .hiddentarget
foo: foo.x .hiddentarget
foo.x: foo.c
touch foo.x
.hiddentarget: foo.x
echo foo.x ok, I believe
这就是您所需要的!
在尝试找出如何阻止名为的目标后,我想到了这个想法.隐藏的目标被错误调用并运行所有隐藏目标。 :)
警告虽然我没有看到任何,但我不确定使用这样的目标名称是否有任何副作用“.目标名称“(以点开头)。
答案2
要隐藏某些目标,您需要破解 shell 的自动完成功能。bash
用途/etc/bash_completion
和/etc/bash_completion.d/*
用途。
不记得 tcsh 是如何做到的。
答案3
我发现这也可以通过以下划线开始目标来实现
_hiddentarget:
@echo "Running hidden target"
答案4
编辑最好阅读其他答案(目标名称以点开头)。但我会在这里回答这个问题,因为编程部分可能会帮助其他类似的问题。
好吧,我花了一些时间才想出解决方案。这是一份(很好的)草案,希望它能顺利完成工作。
您必须编辑该文件 /usr/share/bash-completion/completions/make (对于 Debian Wheezy 或某些与您的系统类似的系统)
在我当前的版本中,第 70 到 73 行的代码为:
70 COMPREPLY=( $( compgen -W "$( make -qp $makef $makef_dir 2>/dev/null | \
71 awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ \
72 {split($1,A,/ /);for(i in A)print A[i]}' )" \
73 -- "$cur" ) )
然后替换为以下代码:
70 HIDDENGOALS="$(make -qp | grep '^\.HIDDENGOALS:' | cut -d' ' -f2- | sed 's/ /\\|/g')"
71 if [[ "$HIDDENGOALS" == "" || "$HIDDENGOALS" == ".HIDDENGOALS:" ]]; then
72 COMPREPLY=( $( compgen -W "$( make -qp $makef $makef_dir 2>/dev/null | \
73 awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ \
74 {split($1,A,/ /);for(i in A)print A[i]}' )" \
75 -- "$cur" ) )
76 else
77 COMPREPLY=( $( compgen -W "$( make -qp $makef $makef_dir 2>/dev/null | \
78 awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ \
79 {split($1,A,/ /);for(i in A)print A[i]}' \
80 | grep -ve "$HIDDENGOALS" )" \
81 -- "$cur" ) )
现在makefile
你可以使用以下内容特殊目标隐藏 bash 自动完成的目标:
.HIDDENGOALS: somegoal anothergoal goalstohide
很像一个.PHONY
特殊的目标(有一些区别)。
小心:
(我)由于此解决方案通过 a 工作grep -ev
,因此特殊目标并不完全如此。它将使用行中的任何内容来匹配正则表达式的方式。
所以,如果你有一个目标,比如说,,copy2
还有另一个copy
,写
.HIDDENGOALS: copy
将隐藏两个目标!
我将这种行为的解决方案作为练习提供给读者! ;)
(二)另一件需要注意的事情是,:
被硬编码为位于 旁边.HIDDENGOALS:
,这意味着尽管目标允许空间就像.PHONY :
,这个特殊的黑客没有。
(三)我认为编辑本地文件而不是更好/usr/share/bash-completion/completions/make,避免升级时丢失信息。但我没有测试任何选项。如果你知道,请评论,我会更新这个答案。
(四)有一个微小的机会好奇的运行目标.隐藏的目标与make .HIDDENGOALS
.这将实现所有隐藏的目标。并且自动完成名称是不可能的,这使我得到了另一个非常简单的答案!