makefile:删除重复的单词而不进行排序

时间:2013-04-22 09:51:16

标签: makefile

是否有可能在没有在makefile 中排序的情况下删除单词列表中的重复项?

$(sort foo bar lose)

确实删除了重复项(在这种情况下对我来说是主要功能),但也排序(在这种情况下对我来说是一个不幸的副作用)。我想避免这种情况。

[更新]

bobbogo 的答案效果非常好。只需记住将v {define uniq用于v3.81并且(不检查此项)define uniq =以用于更高版本。

larsmans '答案效果非常好如果您的记录分隔符不是空格,例如如果你想删除_foo_bar_lose_lose_bar_baz_之类的重复项。请记住使用RSORS awk选项代替tr,并使用$(firstword $(shell ... ))

包装所有选项

4 个答案:

答案 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中创建一个副本来修改其输入,并且它不是递归的。