如何从命令行向Makefile传递参数?
我明白我能做到
$ make action VAR="value"
$ value
Makefile
VAR = "default"
action:
@echo $(VAR)
如何获得以下行为?
$ make action value
value
怎么样
$make action value1 value2
value1 value2
答案 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)
几年后,想为此建议just
:https://github.com/casey/just
action v1 v2=default:
@echo 'take action on {{v1}} and {{v2}}...'