Makefile ifeq 逻辑或
如何使用 make 的 ifeq 运算符执行逻辑 OR?
例如,我有(简化的):
ifeq ($(GCC_MINOR), 4)
CFLAGS += -fno-strict-overflow
endif
ifeq ($(GCC_MINOR), 5)
CFLAGS += -fno-strict-overflow
endif
但想合并这些行。
(是的,是的,自动工具、配置等;对于当前情况来说过于严厉,希望将所有内容保留在 Makefile 中)
[与此问题逻辑相反:如何在“ifeq”语句中使用多个条件]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
在邮件列表存档中可以找到,
可以使用
filter
功能。例如,
过滤器 X, A B
将返回 A、B 中等于 X 的值。请注意,虽然这与上面的示例无关,但这是一个 XOR 运算。也就是说,如果您有类似的内容:
然后执行
make VAR1=4 VAR2=4
,过滤器将返回4 4
,它不等于4
。执行 OR 运算的一种变体是:
使用与空字符串的负比较(如果
GCC_MINOR
与参数不匹配,filter
将返回空字符串) )。使用VAR1
/VAR2
示例,它看起来像这样:这些方法的缺点是您必须确保这些参数始终是单个单词。例如,如果
VAR1
为4 foo
,则过滤结果仍然为4
,并且ifneq
表达式仍然为真的。如果VAR1
为4 5
,则过滤结果为4 5
,且ifneq
表达式为 true。一种简单的替代方法是将相同的操作放在 ifeq 和 else ifeq 分支中,例如:
As found on the mailing list archive,
one can use the
filter
function.For example
filter X, A B
will return those of A,B that are equal to X.Note, while this is not relevant in the above example, this is a XOR operation. I.e. if you instead have something like:
And then do e.g.
make VAR1=4 VAR2=4
, the filter will return4 4
, which is not equal to4
.A variation that performs an OR operation instead is:
where a negative comparison against an empty string is used instead (
filter
will return en empty string ifGCC_MINOR
doesn't match the arguments). Using theVAR1
/VAR2
example it would look like this:The downside to those methods is that you have to be sure that these arguments will always be single words. For example, if
VAR1
is4 foo
, the filter result is still4
, and theifneq
expression is still true. IfVAR1
is4 5
, the filter result is4 5
and theifneq
expression is true.One easy alternative is to just put the same operation in both the
ifeq
andelse ifeq
branch, e.g. like this:您可以引入另一个变量。它不会合并这两项检查,但它至少避免了将主体放入两次:
You can introduce another variable. It doesnt consolidate both checks, but it at least avoids having to put the body in twice:
我认为没有一种简洁、明智的方法可以做到这一点,但是有冗长、明智的方法(例如 Foo Bah 的)和简洁、病态的方法,例如
(如果字符串 $(GCC_MINOR) 则执行命令出现在字符串 4-5) 内。
I don't think there's a concise, sensible way to do that, but there are verbose, sensible ways (such as Foo Bah's) and concise, pathological ways, such as
(which will execute the command provided that the string $(GCC_MINOR) appears inside the string 4-5).
这里有更灵活的变体:它使用外部外壳,但允许检查任意条件:
Here more flexible variant: it uses external shell, but allows to check for arbitrary conditions:
请注意,
ifeq ($(GCC_MINOR),$(filter $(GCC_MINOR),4 5))
将捕获根本未定义 GCC_MINOR 的情况。如果你想捕获 GCC_MINOR==4 或 GCC_MINOR==5 这会起作用:
Note that
ifeq ($(GCC_MINOR),$(filter $(GCC_MINOR),4 5))
will catch the case where GCC_MINOR is not defined at all.If you want to catch GCC_MINOR==4 or GCC_MINOR==5 this will do trick:
在这种情况下,您可以考虑使用的另一个方法是:
我实际上在代码中使用了相同的方法,因为我不想维护单独的
config
或Configure
。但您必须使用可移植的、非贫血的
make
,例如 GNU make (gmake
),而不是 Posix 的make
。并且它没有解决逻辑
AND
和OR
的问题。Another you can consider using in this case is:
I actually use the same in my code because I don't want to maintain a separate
config
orConfigure
.But you have to use a portable, non-anemic
make
, like GNU make (gmake
), and not Posix'smake
.And it does not address the issue of logical
AND
andOR
.如果您希望在逻辑上将多个布尔标志“或”在一起,一种实用的技巧就是简单地让字符串连接起来:if最终结果是一个空字符串,then没有一个选项为真,else非空then至少其中一个已启用:
In the case that you are looking to logically "or" several boolean flags together, one practical hack can be to simply let strings concatenate: if the end result is an empty string, then none of the options were true, else non-empty then at least one of them was enabled: