是否有可能在没有在makefile 中排序的情况下删除单词列表中的重复项?
$(sort foo bar lose)
确实删除了重复项(在这种情况下对我来说是主要功能),但也排序(在这种情况下对我来说是一个不幸的副作用)。我想避免这种情况。
[更新]
bobbogo 的答案效果非常好。只需记住将v {define uniq
用于v3.81并且(不检查此项)define uniq =
以用于更高版本。
larsmans '答案效果非常好如果您的记录分隔符不是空格,例如如果你想删除_foo_bar_lose_lose_bar_baz_
之类的重复项。请记住使用RS
和ORS
awk选项代替tr
,并使用$(firstword $(shell ... ))
答案 0 :(得分:23)
无聊$eval
方法:
define uniq =
$(eval seen :=)
$(foreach _,$1,$(if $(filter $_,${seen}),,$(eval seen += $_)))
${seen}
endef
w := z z x x y c x
$(info $(sort $w))
$(info $(call uniq,$w))
非常恶魔使标准库递归调用(递归使得被认为是非常恶劣的?):
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
值得注意的是,在第二个公式中没有变量被破坏(参见第一个中的seen
)。它只是为了那个(因为 make 中缺少本地人)!
答案 1 :(得分:9)
取决于您需要它的位置以及您是否使用GNU make。如果您只想查看目标先决条件列表,那就像(http://www.gnu.org/software/make/manual/make.html#Quick-Reference)一样简单:
$ ^的值省略了重复的先决条件,而$ +保留了它们并保留了它们的顺序。
所以,像
这样的规则exe: $(OBJS)
$(LD) -o $@ $^
将自动从$(OBJS)过滤重复项,同时仍保留其他项目的顺序。
答案 2 :(得分:6)
您可以echo
通过awk
:
echo foo bar foo baz bar | tr ' ' '\n' | awk '!a[$0]++'
从catonmat中扣除一行内容。
(不要忘记在Makefile中将$
加倍到$$
。)
答案 3 :(得分:0)
以下在GNU make v3.82下对我有用:
uniq = $(eval _uniq := $1)$(strip $(foreach _,$(_uniq),$(if $(filter $_,$(_uniq)),$(eval _uniq := $(filter-out $_,$(_uniq)))$_)))
它不会通过在_uniq
中创建一个副本来修改其输入,并且它不是递归的。