比较生成文件中的整数?

Compare integral numbers in a makefile?

我的 GNU makefile 中有以下内容:

# Undefined Behavior Sanitizer (Clang 3.2 and GCC 4.8 and above)
UBSAN = 0
ifeq ($(findstring ubsan,$(MAKECMDGOALS)),ubsan)
UBSAN = 1
CXXFLAGS += -fsanitize=undefined
endif # UBsan

# Address Sanitizer (Clang 3.2 and GCC 4.8 and above)
ASAN = 0
ifeq ($(findstring asan,$(MAKECMDGOALS)),asan)
ASAN = 1
CXXFLAGS += -fsanitize=address
endif # Asan

# Effectively a NOR
ifneq ($(shell echo $$($(ASAN) * $(UBSAN))),0)
$(error Asan and UBsan are mutually exclusive. Specify only one of them)
endif

想法是检测 make ubsan asan(或用户覆盖 CFLAGSCXXFLAGS),如果两者都指定则出错。

不幸的是,它在没有命令目标的情况下开火:

$ make
/bin/sh: 1: 0: not found
GNUmakefile:64: *** Asan and UBsan are mutually exclusive. Specify only one of them.  Stop.

我也试过引用 "0" 结果相同:ifneq ($(shell echo $$($(ASAN) * $(UBSAN))),"0").

如何比较 makefile 中的两个整数值?

你的问题只是一个简单的错字。

您在 $(shell) 命令的算术扩展中遗漏了一个 (/)

您的 shell 命令是 echo $(0 * 0),shell 将其视为命令替换而不是算术扩展,然后尝试 运行 0 <expansion of all files in the current directory> 0。这就是您收到 /bin/sh: 1: 0: not found 错误消息的原因。

添加缺失的 (/),您的问题就会消失。

ifneq ($(shell echo $$(($(ASAN) * $(UBSAN)))),0)

话虽如此,我根本不会为此使用 shell(它很贵)。

在这种情况下,您要测试的只是 $(ASAN)$(UBSAN) 不是 both 1。所以就断言吧。

ifeq ($(ASAN)$(UBSAN),11)
$(error Asan and UBsan are mutually exclusive. Specify only one of them)
endif

如果你想更安全地手动分配一些其他值(例如 make ASAN=11 或其他),那么你可以做更多的事情:

ifeq ($(filter-out 1,$(ASAN))$(filter-out 1,$(UBSAN)),)
$(error Asan and UBsan are mutually exclusive. Specify only one of them)
endif