Makefile 将论点传递给;“使运行”;
我使用makefile 我有一个名为Makefile 将论点传递给;“使运行”;,makefile,Makefile,我使用makefile 我有一个名为run的目标,它运行构建目标。简化后,它看起来如下所示: prog: .... ... run: prog ./prog 有什么方法可以传递参数吗?所以 make run asdf --> ./prog asdf make run the dog kicked the cat --> ./prog the dog kicked the cat 谢谢 对于标准make,可以通过如下定义宏来传递参数 make run arg1=asdf
run
的目标,它运行构建目标。简化后,它看起来如下所示:
prog: ....
...
run: prog
./prog
有什么方法可以传递参数吗?所以
make run asdf --> ./prog asdf
make run the dog kicked the cat --> ./prog the dog kicked the cat
谢谢 对于标准make,可以通过如下定义宏来传递参数
make run arg1=asdf
run: ./prog $(arg1)
etc
$ make run arg1 arg2
然后像这样使用它们
make run arg1=asdf
run: ./prog $(arg1)
etc
$ make run arg1 arg2
参考
Microsoft的我不知道如何准确地实现您的目标,但解决方法可能是:
run: ./prog
./prog $(ARGS)
然后:
否。请查看GNU make手册页中的语法 make[-f makefile][options]。。。[目标]
您可以指定多个目标,因此“否”(至少以您指定的确切方式为否)。
run:./prog
看起来有点奇怪,因为右侧部分应该是目标,所以run:prog
看起来更好
我只建议:
.PHONY: run
run:
prog $(arg1)
我想补充一点,可以传递参数:
make arg1=“asdf”run
arg1=“asdf”使运行
这个问题已经问了三年了,但无论如何 如果您使用的是GNU make,这很容易做到。唯一的问题是
make
会将命令行中的非选项参数解释为目标。解决方案是将它们变成无所事事的目标,这样make
就不会抱怨:
# If the first argument is "run"...
ifeq (run,$(firstword $(MAKECMDGOALS)))
# use the rest as arguments for "run"
RUN_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
# ...and turn them into do-nothing targets
$(eval $(RUN_ARGS):;@:)
endif
prog: # ...
# ...
.PHONY: run
run : prog
@echo prog $(RUN_ARGS)
运行此命令将提供:
$ make run foo bar baz
prog foo bar baz
这是我的例子。请注意,我是在Windows 7下编写的,使用的是Dev Cpp附带的mingw32-make.exe。(我有c:\Windows\System32\make.bat,因此该命令仍然称为“make”。) 定期清洁的用法:
make clean
在mydir/中清理和创建备份的用法:
make clean backup=mydir
下面是另一个解决方案,它可以帮助解决其中一些用例:
test-%:
$(PYTHON) run-tests.py $@
换句话说,选择一些前缀(
test-
,在本例中),然后将目标名称直接传递给程序/运行程序。我想如果涉及到一些运行程序脚本,可以将目标名称展开为对底层程序有用的内容,那么这将非常有用。您可以将变量传递到Makefile,如下所示:
run:
@echo ./prog $$FOO
用法:
$ make run FOO="the dog kicked the cat"
./prog the dog kicked the cat
$ make run the dog kicked the cat
./prog the dog kicked the cat
或:
或者使用以下提供的解决方案: -与任何任务名称匹配的规则; -空配方=什么也不做 用法:
$ make run FOO="the dog kicked the cat"
./prog the dog kicked the cat
$ make run the dog kicked the cat
./prog the dog kicked the cat
可以在命令行中显式提取每个第n个参数。为此,您可以使用变量
MAKECMDGOALS
,它保存给定给“make”的命令行参数列表,并将其解释为目标列表。如果要提取第n个参数,可以将该变量与“word”函数结合使用,例如,如果要提取第二个参数,可以将其存储在变量中,如下所示:
second_argument := $(word 2, $(MAKECMDGOALS) )
对此不太自豪,但我不想传入环境变量,所以我改变了运行一个固定命令的方式:
run:
@echo command-you-want
这将打印您要运行的命令,因此只需在子shell中对其求值:
$(make run) args to my command
TL;博士,别这么做
$ make run arg
而是创建脚本build\u和\u run\u prog.sh
:
#! /bin/sh
# rebuild prog if necessary
make prog
# run prog with some arguments
./prog "$@"
这样做:
$ ./build_and_run_prog.sh arg
请继续阅读,了解为什么这是最合理的选择,以及为什么最好避免其他选择
对所述问题的回答:如何将参数传递给make目标 您可以在配方中使用变量
run: prog
./prog $(var)
run: prog
./prog $(var)
然后将变量赋值作为参数传递给make
$ make run var=arg
这将执行/prog arg
但要小心陷阱。我将在下面进一步阐述这种方法和其他方法的缺陷
回答问题背后的假设意图:您希望运行带有一些参数的
prog
,但如有必要,请在运行之前重新生成它
创建一个脚本,必要时进行重建,然后使用args运行prog
构建和运行程序sh
:
#! /bin/sh
# rebuild prog if necessary
make prog
# run prog with some arguments
./prog "$@"
run: prog
./prog $(filter-out $@, $(MAKECMDGOALS))
%:
@true
ifeq (run, $(firstword $(MAKECMDGOALS)))
runargs := $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))
$(eval $(runargs):;@true)
endif
run:
./prog $(runargs)
这个脚本使意图非常清楚。它使用make来做它有好处的事情:建筑。它使用一个shell脚本来做它所擅长的事情:批处理
此外,您还可以使用shell脚本的充分灵活性和表达能力来执行任何可能需要的操作,而不需要makefile的所有警告
此外,调用语法现在实际上是相同的:
$ ./build_and_run_prog.sh foo "bar baz"
与之相比:
$ ./prog foo "bar baz"
对比
$ make run var="foo bar\ baz"
make如何处理参数的背景说明:
#! /bin/sh
# rebuild prog if necessary
make prog
# run prog with some arguments
./prog "$@"
run: prog
./prog $(filter-out $@, $(MAKECMDGOALS))
%:
@true
ifeq (run, $(firstword $(MAKECMDGOALS)))
runargs := $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))
$(eval $(runargs):;@true)
endif
run:
./prog $(runargs)
Make不是为向目标传递参数而设计的。命令行上的所有参数都被解释为目标(也称为目标)、选项或变量赋值
因此,如果您运行以下命令:
$ make run foo --wat var=arg
make将run
和foo
解释为目标(targets),根据它们的食谱进行更新<代码>--wat作为make的一个选项。和var=arg
作为变量赋值
有关更多详细信息,请参阅:
还有
为什么我不建议变量赋值
$ make run var=arg
以及配方中的变量
run: prog
./prog $(var)
run: prog
./prog $(var)
这是将参数传递给配方的最“正确”和最直接的方法。但是,虽然它可以用来运行一个带有参数的程序,但它肯定不是设计用来这样使用的。见
在我看来,这有一个很大的缺点:您要做的是使用参数arg
运行prog
。但不是写:
$ ./prog arg
你在写:
$ make run var=arg
当尝试传递多个参数或包含空格的参数时,这会变得更加尴尬:
$ make run var="foo bar\ baz"
./prog foo bar\ baz
argcount: 2
arg: foo
arg: bar baz
与之相比:
$ ./prog foo "bar baz"
argcount: 2
arg: foo
arg: bar baz
作为记录,这是我的prog
的样子:
#! /bin/sh
echo "argcount: $#"
for arg in "$@"; do
echo "arg: $arg"
done
还请注意,您不应在makefile中的引号中添加$(var)
:
run: prog
./prog "$(var)"
因为prog
总是只得到一个参数:
$ make run var="foo bar\ baz"
./prog "foo bar\ baz"
argcount: 1
arg: foo bar\ baz
这就是我反对这条路线的原因
为了完整起见,这里还有一些“传递参数以使其运行”的其他方法 方法1:
#! /bin/sh
# rebuild prog if necessary
make prog
# run prog with some arguments
./prog "$@"
run: prog
./prog $(filter-out $@, $(MAKECMDGOALS))
%:
@true
ifeq (run, $(firstword $(MAKECMDGOALS)))
runargs := $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))
$(eval $(runargs):;@true)
endif
run:
./prog $(runargs)
从目标列表中筛选出当前目标。创建catch-all目标(%
),该目标不做任何事情来默默地忽略另一个goa
--xyz-enabled=false
# the other technique to invalidate other targets is still required, see linked post
run:
@echo ./prog $(-*-command-variables-*-) $(filter-out $@,$(MAKECMDGOALS))`
make run -- config --xyz-enabled=false over=9000 --foo=bar show isit=alwaysreversed? --help
./prog isit=alwaysreversed? --foo=bar over=9000 --xyz-enabled=false config show --help
MAKEFLAGS = -- isit=alwaysreverse? --foo=bar over=9000 --xyz-enabled=false
MAKEOVERRIDES = isit=alwaysreverse? --foo=bar over=9000 --xyz-enabled=false