如何从命令行传递参数到Makefile?

问题描述 投票:84回答:3

如何从命令行传递参数到Makefile?

我明白我能做到

$ make action VAR="value"
$ value

Makefile

VAR = "default"
action:
    @echo $(VAR)

我如何获得以下行为?

$ make action value
value

?

怎么样

$make action value1 value2
value1 value2
command-line parameters makefile arguments
3个回答
169
投票

你可能不应该这样做;你打破了Make如何运作的基本模式。但这里是:

action:
        @echo action $(filter-out $@,$(MAKECMDGOALS))

%:      # thanks to chakrit
    @:    # thanks to William Pursell

编辑: 要解释第一个命令,

$(MAKECMDGOALS)是命令行中拼写的“目标”列表,例如“action value1 value2”。

$@是规则目标名称的automatic variable,在这种情况下是“行动”。

filter-out是一个从列表中删除一些元素的函数。所以$(filter-out bar, foo bar baz)返回foo baz(它可能更微妙,但我们在这里不需要精妙)。

将这些放在一起,$(filter-out $@,$(MAKECMDGOALS))返回命令行中指定的目标列表,而不是“action”,可能是“value1 value2”。


7
投票

从我的角度来看,更容易做下面的示例。考虑一项任务:

provision:
        ansible-playbook -vvvv \
        -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory \
        --private-key=.vagrant/machines/default/virtualbox/private_key \
        --start-at-task="$(AT)" \
        -u vagrant playbook.yml

现在,当我想要调用它时,我只需执行以下操作:

AT="build assets" make provision

要不就:

在这种情况下make provision AT是一个空字符串


7
投票

这是基于@ Beta的通用工作解决方案

我在我的Makefile上使用GNU Make 4.1和SHELL=/bin/bash,所以YMMV!

这允许我们接受额外的参数(当我们得到一个不匹配的工作时,不做任何事情,而不是抛出错误)。

%:
    @:

这是一个宏,它为我们得到了args:

args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}`

这是一个可能称之为的工作:

test:
    @echo $(call args,defaultstring)

结果将是:

$ make test
defaultstring
$ make test hi
hi

注意!使用“任务文件”可能会更好,这是一种类似于make的bash模式,只是没有Maketools的细微差别。见https://github.com/adriancooney/Taskfile

© www.soinside.com 2019 - 2024. All rights reserved.