支持 make 的参数

支持 make 的参数

我知道你可以传递参数,例如make foo=bar。我想知道我是否可以只用一个参数来做到这一点,而不用变量。例如,这就是我想要做的:

hello:
    echo "Hello, $1!"

在 Bash 中,$1 是通过函数传递的第一个参数。如果我运行make hello 'world',那么它应该输出Hello, world!。这可能吗?

答案1

我完全同意 DWD 和 Thomas 的观点。但是,如果出于某种原因,您被迫使用make和 a Makefile,请记住,make将把所有既不是定义也不是执行标志的参数视为目标。它将尝试按顺序一次更新所有参数。所以:

make hello VAR=value how are -d you --debug=n

将把-d--debug=n视为执行标志(或选项)和VAR=value变量 的定义VAR。所有其他参数将被视为目标。

如果您使用的是 GNU make,则可以从某些特殊变量中受益,例如MAKECMDGOALS包含要更新的目标的完整列表。借助firstwordwordlist和等函数words,我们可以将第一个目标与其余目标隔离开来:

# Takes the first target as command
Command := $(firstword $(MAKECMDGOALS))
# Skips the first word
Arguments := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))

规则hello非常简单:

hello:
    @echo "Hello, "$(Arguments)"!";

如果您运行make hello 'world',您将获得所期望的结果,但 make 还将尝试将其world作为目标进行构建,并且对于您在 hello 之后传递的任何其他字符串也是如此。

解决方案将随最后一个资源规则一起提供:%::。当没有其他规则可以应用时,将对其进行评估。为了保持安静(无输出,无错误),配方可以是@true

%::
    @true

总而言之,最终结果Makefile如下:

Command := $(firstword $(MAKECMDGOALS))
Arguments := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))

hello:
    @echo "Hello, "$(Arguments)"!";

%::
    @true

这有很多限制。第一个限制是,如果你将指令集扩展到简单的 之外hello,那么除了被 回显之外,这些新目标还会被评估hello。另一个限制与无效命令处理有关。你必须使用函数filter来确定目标是行中的第一个(实际命令)还是命令的参数。

相关内容