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

问题描述 投票:14回答:3

是否有可能删除单词列表中的重复项而不在makefile中排序?

$(sort foo bar lose)

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

[更新]

bobbogo的答案很有效。只记得使用define uniq for v3.81和(没有检查这个)define uniq =的更高版本。

如果您的记录分隔符不是空格,例如larsmans的答案也很有效。如果你想从_foo_bar_lose_lose_bar_baz_等删除重复项。只记得使用RSORS awk选项而不是tr,并用$(firstword $(shell ... ))包装它们

makefile
3个回答
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)。这是优选的(鉴于制造中缺乏当地人)!


9
投票

取决于您需要它的位置以及您是否使用GNU make。如果您只想要列出目标先决条件列表,那就像(http://www.gnu.org/software/make/manual/make.html#Quick-Reference)一样简单:

$ ^的值省略了重复的先决条件,而$ +保留了它们并保留了它们的顺序。

所以,像一个规则

exe: $(OBJS)
        $(LD) -o $@ $^

将自动从$(OBJS)过滤重复项,同时仍保持其他项目的顺序相同。


6
投票

你可以通过echo awk的话:

echo foo bar foo baz bar | tr ' ' '\n' | awk '!a[$0]++'

catonmat取出的重叠单线。

(别忘了在Makefile中将$加倍到$$。)

© www.soinside.com 2019 - 2024. All rights reserved.