首页 > 解决方案 > 来自 make 命令的 Makefile 函数,而不是 shell 命令

问题描述

有没有办法从 Makefile 命令中创建多行函数?

我知道我们可以做这样的事情来将(shell命令的)配方封装为一个函数:

define function
    @echo 'First argument: $1'
    @echo 'Second argument: $2'
endef

.PHONY test-function
test-function:
    $(call function, a, b)

有了这个,运行make test-function将给出输出:

First argument: a
Second argument: b

我也知道我们可以将call指令与由 make 语法/指令组成的单行宏一起使用(示例取自此处):

pathsearch = $(firstword $(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH)))))

LS := $(call pathsearch,ls)

但是假设我想要call一个由多个 make 命令组成的宏,包括条件。我将如何实现这一目标?

当我make build-type=API build使用以下 Makefile 运行时:

define check-arguments
ifeq ($1, api)
     @echo 'Building API'
else ifeq ($1, service)
     @echo 'Building Service'
else
     $$(error 'Build type must be API or Service')
endif
endef

.PHONY: build
build:
$(call check-arguments, $(build-type))
    @echo 'Starting build'
    ...
    ...

我不断收到错误Makefile:13: *** missing separator. Stop.

标签: makefile

解决方案


您可以使用eval. GNU Make Manual 指出:

...it [ eval] 允许您定义非恒定的新 makefile 结构;这是评估其他变量和函数的结果。

eval将解析ifeq$(error)作为 makefile 的一部分,而不是作为配方的命令。

要记住的一件事是它自己eval解析其输入,而不考虑 makefile 的周围语法。这意味着您不能使用它来仅定义规则的一部分,例如在您的示例中:

build:
$(call check-arguments, $(build-type))

如果我们使用$(eval $(call check-arguments, $(build-type))), thenevalcheck-arguments自行解析扩展并抱怨,因为配方没有目标。(请参阅此答案。)这里的解决方案是以某种方式包含build:在内check-arguments


推荐阅读