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

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

我知道我能做到

$ make action VAR="value"
$ value

Makefile

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

我如何得到以下行为?

$ make action value
value

怎么样

$make action value1 value2
value1 value2
208615 次浏览

您可能不应该这样做,因为这样做打破了 Make 的基本工作模式:

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


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

编辑:
为了解释第一个命令,

$(MAKECMDGOALS)是在命令行上输出的“目标”列表,例如“ action value1 value2”。

$@是表示规则目标名称的 自动变量,在本例中为“ action”。

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

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

更简单的方法。考虑一项任务:

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

下面是一个基于@Beta 的通用工作解决方案

我正在使用 GNU Make 4.1,在 Makefile 顶部使用 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”,这是一种 bash 模式,其工作方式与 make 类似,只是没有 Maketools 的细微差别。参见 https://github.com/adriancooney/Taskfile

别这么做

$ make action value1 value2

而是创建脚本:

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

然后这样做:

$ ./buildthenaction.sh value1 value2

为了更多的解释为什么这样做和 makefile 黑客的警告阅读我的答案,另一个非常相似,但似乎没有重复的问题: 将参数传递到“ make run”

几年后,要建议 just为此: https://github.com/casey/just

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

定义变量和调用 make 而不是使用参数会更好:

马克菲尔

action: ## My action helper
@echo $$VAR_NAME

晚期

> VAR_NAME="Hello World" make action
Hello World