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

时间:2011-06-08 02:32:38

标签: command-line parameters makefile arguments

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

我明白我能做到

$ make action VAR="value"
$ value

Makefile

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

如何获得以下行为?

$ make action value
value

怎么样

$make action value1 value2
value1 value2

5 个答案:

答案 0 :(得分:173)

你可能不应该这样做;你打破了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”。

答案 1 :(得分:9)

以下是基于@ Beta&#39的通用工作解决方案

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

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

%:
    @:

这是一个让我们知道的宏:

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

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

test:
    @echo $(call args,defaultstring)

结果将是:

$ make test
defaultstring
$ make test hi
hi

请注意!你可能最好使用一个" Taskfile",这是一个类似于make的bash模式,只是没有Maketools的细微差别。见https://github.com/adriancooney/Taskfile

答案 2 :(得分: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

或只是:

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

答案 3 :(得分:0)

不要尝试这样做

$ make action value1 value2

代替创建脚本:

#! /bin/sh
# rebuild if necessary
make
# do action with arguments
action "$@"

然后执行以下操作:

$ ./buildthenaction.sh value1 value2

更多解释,为什么这样做以及makefile hackage警告说明了我对另一个非常相似但似乎不是重复的问题的回答:Passing arguments to "make run"

答案 4 :(得分:0)

几年后,想为此建议justhttps://github.com/casey/just

action v1 v2=default:
    @echo 'take action on {{v1}} and {{v2}}...'