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


Answers:


212

您可能不应该这样做;您正在打破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”)。


1
$(shell echo $(MAKECMDGOALS) | sed 's!^.* $@ !!')省略之前的所有目标,仅将以下内容作为论点:make target1 target2 action value1 value2
Evgeniy Generalov

1
原谅我的无知。我已经尝试使用Google搜索%:@:但是无法找到有关这些“指令”(或称为“指令”)的信息。你能解释一下吗?
2014年

15
@Jon:手册在这里。由%:和组成的部分@:规则。目标名称%表示这是匹配任何内容的规则;也就是说,如果Make无法找到任何其他方式来构建您告诉它要构建的事物,它将执行该规则。这@:食谱 ; 该:方法什么也不做,和@手段做默默。
2014年

谢谢。我一直在阅读该手册,起初没有考虑,%:实际上% :是通配符类型的目标名称。我在该手册页中没有看到任何关于@:……的信息,但这确实表明“不做任何事”规则仅;在目标规范后面加上一个“后缀” ,因此写成% : ;“通配符会不会更准确” -没有”规则?
2014年

1
filter-out当操作是命令行上指定的目标的依赖项时,此操作将不起作用,因为$@它将设置为依赖项的名称,而不是命令行中调用的原始参数。相反,我分配MAKECMDGOALS了一个外壳数组,然后删除了第一个元素:@ args=($(MAKECMDGOALS)); args=("$${args[@]:1}")
Gingi 2015年

18

这是基于@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
Abdullah Al Maruf-Tuhin

11

容易得多的方式。考虑一个任务:

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是一个空字符串


-2

不要尝试这样做

$ make action value1 value2

而是创建脚本:

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

并执行以下操作:

$ ./buildthenaction.sh value1 value2

以获得更多解释,为什么这样做和makefile hackage警告说明了我对另一个非常相似但似乎并非重复的问题的回答:将参数传递给“ make run”

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.