Makefile ifeq逻辑或


92

如何使用make ifeq运算符执行逻辑或?

例如,我有(简体):

ifeq ($(GCC_MINOR), 4)
    CFLAGS += -fno-strict-overflow
endif
ifeq ($(GCC_MINOR), 5)
    CFLAGS += -fno-strict-overflow
endif

但想巩固这些界限。

(是的,是的,自动工具,配置等;对于当前情况而言过于笨拙,想将所有内容保留在Makefile中)

[这个问题的逻辑对立:如何在“ ifeq”语句中使用多重条件 ]



1
不要以为是骗子,链接的问题与链接ifdef运算符有关,这个问题与链接ifeq运算符有关,类似,但是答案肯定不同。
专利

Answers:


103

如邮件列表存档中所示,

一个可以使用过滤功能。

例如

 ifeq ($(GCC_MINOR),$(filter $(GCC_MINOR),4 5))

过滤器X,AB将返回等于X的A,B。

这是一个变化

 ifneq (,$(filter $(GCC_MINOR),4 5))

而是使用对空字符串的否定比较(如果GCC_MINOR与参数不匹配,过滤器将返回一个空字符串)

这些方法的缺点是参数必须是单个单词。


7
一个较晚的注释:在上面的两个变体中,如果$(GCC_MINOR)为空,则第一个将解析为true,而第二个则不会(因此,从广义上讲,第二个是更好的解决方案)。
约翰

1
实际上,应该是ifneq (,$(filter 4 5,$(GCC_MINOR))):)
Tuxdude 2014年

2
为简单起见,最好保持原样?
杰森

另一个注意事项:这不能用作一般的 OR语句。我们有一些地方要检查if(flagA == TRUE || flagB == true),但如果您都这样做$(filter true, $(flagA) $(flagB)并且都正确,那么您会得到ifeq(true, true true)
Charlie Su

27

您可以引入另一个变量。它不会合并两个检查,但至少避免了必须将身体放两次:

do_it = 
ifeq ($(GCC_MINOR), 4)
    do_it = yes
endif
ifeq ($(GCC_MINOR), 5)
    do_it = yes
endif
ifdef do_it
    CFLAGS += -fno-strict-overflow
endif

7
这种大规模的可维护性似乎并没有对我非常好:/话又说回来,一旦我们开始谈论的规模,我想我们谈论的自动工具
帕特

2
@Pat:我更喜欢这种方法,我可以将分配放在Makefile中的一个位置,可以使用ifeq / else ifeq / else与更多的值进行比较,而不是使用过滤器函数,该函数可能会使读取行很长。
jcarballo 2014年

15

我认为没有做到这一点的简洁,明智的方法,但是有一些冗长,明智的方法(例如,Foo Bah的方法)和简洁,病理性的方法(例如,

ifneq (,$(findstring $(GCC_MINOR),4-5))
    CFLAGS += -fno-strict-overflow
endif

(只要字符串$(GCC_MINOR)出现在字符串4-5内,它将执行命令)。


4
不管是好是坏(可能更糟),这只是我一直在寻找的肮脏技巧。感谢

1
除了Makefile 中的所有内容都是病态的事实之外,我认为这根本不是病态的。真的很优雅。我已经阅读了四种或五种不同的方法来实现此目的,而您的方法到目前为止是最容易理解的。
Michael Geary

8

这里是更灵活的变体:它使用外壳,但是允许检查任意条件:

ifeq ($(shell test ".$(GCC_MINOR)" = .4  -o  \
                   ".$(GCC_MINOR)" = .5  -o  \
                   ".$(TODAY)"     = .Friday  &&  printf "true"), true)
    CFLAGS += -fno-strict-overflow
endif

1
ifeq ($(GCC_MINOR), 4)
    CFLAGS += -fno-strict-overflow
endif
ifeq ($(GCC_MINOR), 5)
    CFLAGS += -fno-strict-overflow
endif

在这种情况下,您可以考虑使用的另一个是:

GCC42_OR_LATER = $(shell $(CXX) -v 2>&1 | $(EGREP) -c "^gcc version (4.[2-9]|[5-9])")

# -Wstrict-overflow: http://www.airs.com/blog/archives/120
ifeq ($(GCC42_OR_LATER),1)
  CFLAGS += -Wstrict-overflow
endif

实际上,我在代码中使用了相同的代码,因为我不想维护单独的configConfigure

但是,您必须使用可移植的非贫血类make,例如GNU make(gmake),而不是Posix的make

而且它并没有解决逻辑AND和逻辑问题OR

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.