Makefile:具有默认参数的宏

Makefile:具有默认参数的宏,makefile,gnu-make,Makefile,Gnu Make,考虑以下Makefile: MAKEFLAGS += --warn-undefined-variables define foobar echo "$(1)" endef .PHONY: all all: $(foobar) 有没有一种方法可以使宏具有默认参数而不产生未定义的变量警告? 我的意思是:有时我用参数调用“foobar”,但有时不是。在后一种情况下,我希望有$(1)的默认值。GNU make语法非常有限;它不是一种成熟的编程语言,所以缺少很多东西,比如make宏中的默认参

考虑以下Makefile:

MAKEFLAGS += --warn-undefined-variables

define foobar
echo "$(1)"
endef

.PHONY: all
all:
    $(foobar)
有没有一种方法可以使宏具有默认参数而不产生未定义的变量警告?
我的意思是:有时我用参数调用“foobar”,但有时不是。在后一种情况下,我希望有$(1)的默认值。

GNU make语法非常有限;它不是一种成熟的编程语言,所以缺少很多东西,比如make宏中的默认参数

但是shell是一种编程语言!为什么不在目标的命令中实现您的需求?可以使用类似以下内容:

all:
    if test "$(SOMECONDITION)"; then \
         do_one_thing; \
    else \
         do_something_else; \
    fi

无法在宏中设置默认值,但可以在展开参数时轻松添加默认值:

1:=

define foobar
echo "$(if $1,$1,default)"
endef

all:
        $(foobar)
        $(call foobar,biz)

$ make
echo "default"
default
echo "biz"
biz

如果您多次使用该参数,会有点烦人,因为每次使用都必须使用
if

GNU make有一个不错的解决方案。不知道它有多便携

使用包含相当混乱的逻辑的全局变量,使用命名约定以避免冲突:

# foo.mk
MAKEFLAGS += --warn-undefined-variables

foobar_p1_default = default parameter
foobar_p1 = $(if $(filter undefined,$(origin 1)),$(foobar_p1_default),$1)
define foobar
@echo $@: "$(foobar_p1)"
endef

.PHONY: all defaulted global local
all : defaulted global local
defaulted:
    $(foobar)

variable = global value
global local:
    $(call foobar,parameter was $(variable))

local: variable = target specific value
结果是:

$ make -f foo.mk 
defaulted: default parameter
global: parameter was global value
local: parameter was target specific value

这是我尝试的第一件事情之一,但它仍然会引发一个“未定义变量”警告。尝试将
MAKEFLAGS+=--警告未定义的变量
添加到代码段以进行验证。我还试图找到一种使用$(origin)函数的聪明方法,但到目前为止没有成功。IMO的“警告未定义的变量”充其量只是边际效用。但是,您可以通过将“1”定义为具有空值的全局变量来避免警告,正如我在上面编辑的那样。不,我需要在宏中抽象出此逻辑。它在很多地方都有使用。我只需要一个宏,在不发出警告的情况下,允许我传递或不传递参数。在后一种情况下,将使用默认值。@MarkTayo如果arg是特殊的,例如,当它是0、负数或空字符串时,您能让宏忽略它吗?你应该为这两种用途给我们一个具体的例子。我正在寻找一个干净的解决方案,而不是给一个特殊的arg赋予特殊的意义。只有缺少arg才有意义(即使用默认值)。@MarkTayo您不能使用未实现的功能。如果您坚持您对“clean”的定义,那么您所能做的就是让MadScientist在GNU make for you--或UTSL中实现它,然后黑客攻击。刚刚找到了“clean”解决方案:
$(如果$(filter undefined,$(origin 1)),默认值,$(1))
。它起作用了。现在最好是有一个“元宏”。可以从另一个宏调用的内容如下:
$(调用默认值,$(1),mydefaultvalue)
。这将是解决方案。。。一般与清洁。。。