Makefile 将附加参数从 make 命令传递给目标命令

seb*_*n_t 5 bash makefile docker-compose

我有一个定义 docker-compose 项目的 Makefile。它基本上为我组装了一个命令:

COMMAND := docker-compose --project-name=$(PREFIX) --file=$(FILE_PATH)

up:
    $(COMMAND) up -d
Run Code Online (Sandbox Code Playgroud)

我想添加一个target命名dc的,我可以传递我想要的任何参数。

我知道有一个解决方案:

target:
    $(COMMAND) $(ARGS)
Run Code Online (Sandbox Code Playgroud)

然后用make target ARGS="--help"例如调用它。

但是没有比 bash 更简单的方法$@吗?我想跳过 ARGS=... 部分并将所有内容发送到target名称后的命令。

Har*_*nry 5

您可以编写一个 bash 包装脚本来执行您想要的操作:

#/bin/bash
make target ARGS=\"$@\"
Run Code Online (Sandbox Code Playgroud)

您不想在 make 中执行此操作的原因是 make 在解析 makefile 本身之前解析命令行参数,因此当您读取 makefile 时,目标、变量等已经设置。这意味着 make 已经将额外的参数解释为新的目标、变量等。


Mad*_*ist 5

并不真地。make 程序将所有参数(不包含=)解释为要构建的目标名称,您无法覆盖它。因此,即使您可以获得命令行上给出的参数列表(通过 GNU make-specific$(MAKECMDGOALS)变量),您也无法阻止这些参数被视为目标。

你可以做这样的事情,这是令人难以置信的hacky:

KNOWN_TARGETS = target

ARGS := $(filter-out $(KNOWN_TARGETS),$(MAKECMDGOALS))

.DEFAULT: ;: do nothing

.SUFFIXES:
target:
        $(COMMAND) $(ARGS)
Run Code Online (Sandbox Code Playgroud)

(未经测试)。这里的问题是您必须KNOWN_TARGETS与所有“真实”目标保持同步,以便您可以将它们从命令行给出的目标列表中删除。然后添加.DEFAULT将为任何不知道如何构建的目标运行的目标,它什么也不做。重置.SUFFIXES元目标以删除内置规则。

我怀疑这仍然会有奇怪的边缘情况,它不起作用。

另请注意,您不能只--help在 make 命令行中添加选项,因为 make 会自行解释它们。您必须为它们加上前缀--以强制 make 忽略它们:

make target -- --help
Run Code Online (Sandbox Code Playgroud)

另一种选择是添加这样的目标:

target%:
        $(COMMAND) $*
Run Code Online (Sandbox Code Playgroud)

然后你可以运行这个:

make "target --help"
Run Code Online (Sandbox Code Playgroud)

但是你必须包括引号。

一般来说,我只是建议你重新考虑你想要做什么。