Makefile函数来自make命令,而不是shell命令

Makefile函数来自make命令,而不是shell命令,makefile,Makefile,有没有办法用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:

有没有办法用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
我还知道,我们可以将
调用
指令与包含make语法/指令的单行宏一起使用(示例取自:

但假设我想调用一个由多个make命令(包括条件)组成的宏。我将如何实现这一点

当我使用以下Makefile运行
makebuildtype=API build
时:

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:**缺少分隔符。停止。

您可以使用。GNU手册规定:

…它[
eval
]允许您定义非常量的新makefile构造;这是评估其他变量和函数的结果

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

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

build:
$(call check-arguments, $(build-type))
如果我们使用
$(eval$(调用检查参数,$(构建类型))
,那么
eval
将自己解析
检查参数的扩展,并抱怨,因为配方没有目标。(请参阅。)这里的解决方案是以某种方式将
构建:
包含在
检查参数中。

虽然使用
$(eval)
很好,但我想推荐一种不同的方法,基于目标解析而不是条件,如下所示:

$ cat Makefile
supported_build_types := api service

.PHONY: build
build: build-$(build-type)

.PHONY: $(addprefix build-,$(supported_build_types))
$(addprefix build-,$(supported_build_types)): build-%:
        @echo 'Building $*'
        @echo 'Starting build'

.PHONY: build-
build-:
        $(error Must provide build-type of: $(supported_build_types))

.PHONY: build-%
build-%:
        $(error Unsupported build type: $*. Must be one of: $(supported_build_types))
这使得扩展和维护更容易,同时避免了
$(eval)
s、
$(call)
s和适当转义的干扰

运行支持的生成类型:

$ make build build-type=api
Building api
Starting build

$ make build build-type=service
Building service
Starting build
无效的生成类型:

$ make build build-type=foo
Makefile:17: *** Unsupported build type: foo. Must be one of: api service.  Stop.
$ make build
Makefile:13: *** Must provide build-type of: api service.  Stop.
缺少生成类型:

$ make build build-type=foo
Makefile:17: *** Unsupported build type: foo. Must be one of: api service.  Stop.
$ make build
Makefile:13: *** Must provide build-type of: api service.  Stop.

在示例Makefile的第7行中,
build-%
后面的冒号表示什么?这使我对制造的理解变得不正常。我以为
build-%
是先决条件(它显示在冒号后面)…但是
build-%
后面也有一个冒号…那么现在呢?它被称为冒号。显然,它只允许模式规则应用于一组选定的目标。(这也是为什么最后的
build-%:
规则可以作为一种后备方案。)