如何从命令行将参数传递给Makefile?
我知道我能做
$ make action VAR="value"
$ value
与 Makefile
VAR = "default"
action:
@echo $(VAR)
如何获得以下行为?
$ make action value
value
?
怎么样
$make action value1 value2
value1 value2
如何从命令行将参数传递给Makefile?
我知道我能做
$ make action VAR="value"
$ value
与 Makefile
VAR = "default"
action:
@echo $(VAR)
如何获得以下行为?
$ make action value
value
?
怎么样
$make action value1 value2
value1 value2
Answers:
您可能不应该这样做;您正在打破Make运作方式的基本模式。但是这里是:
action:
@echo action $(filter-out $@,$(MAKECMDGOALS))
%: # thanks to chakrit
@: # thanks to William Pursell
编辑:
解释第一个命令,
$(MAKECMDGOALS)
是在命令行中阐明的“目标”列表,例如“ action value1 value2”。
$@
是规则目标名称的自动变量,在这种情况下为“操作”。
filter-out
是从列表中删除某些元素的函数。因此$(filter-out bar, foo bar baz)
回报foo baz
(可能会更微妙,但在这里我们不需要微妙)。
将它们放在一起并$(filter-out $@,$(MAKECMDGOALS))
返回在命令行上指定的目标列表,而不是“ action”(可能是“ value1 value2”)。
$(shell echo $(MAKECMDGOALS) | sed 's!^.* $@ !!')
省略之前的所有目标,仅将以下内容作为论点:make target1 target2 action value1 value2
%:
,@:
但是无法找到有关这些“指令”(或称为“指令”)的信息。你能解释一下吗?
%:
实际上% :
是通配符类型的目标名称。我在该手册页中没有看到任何关于@:
……的信息,但这确实表明“不做任何事”规则仅;
在目标规范后面加上一个“后缀” ,因此写成% : ;
“通配符会不会更准确” -没有”规则?
filter-out
当操作是命令行上指定的目标的依赖项时,此操作将不起作用,因为$@
它将设置为依赖项的名称,而不是命令行中调用的原始参数。相反,我分配MAKECMDGOALS
了一个外壳数组,然后删除了第一个元素:@ args=($(MAKECMDGOALS)); args=("$${args[@]:1}")
这是基于@Beta的通用工作解决方案
我SHELL=/bin/bash
在我的Makefile上使用GNU Make 4.1 ,所以YMMV!
这使我们可以接受额外的参数(通过在获得不匹配的工作时不执行任何操作,而不是抛出错误)。
%:
@:
这是一个为我们获取参数的宏:
args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}`
这是一项可能称为“工作”的工作:
test:
@echo $(call args,defaultstring)
结果将是:
$ make test
defaultstring
$ make test hi
hi
注意!使用“任务文件”可能是更好的选择,它是一种bash模式,其工作方式与make类似,只是没有Maketools的细微差别。参见https://github.com/adriancooney/Taskfile
tab
之前@echo
没有space
。
容易得多的方式。考虑一个任务:
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
是一个空字符串
不要尝试这样做
$ make action value1 value2
而是创建脚本:
#! /bin/sh
# rebuild if necessary
make
# do action with arguments
action "$@"
并执行以下操作:
$ ./buildthenaction.sh value1 value2
以获得更多解释,为什么这样做和makefile hackage警告说明了我对另一个非常相似但似乎并非重复的问题的回答:将参数传递给“ make run”