如果你正在使用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
8
您可以将变量传递给Makefile,如下所示:
run:
@echo ./prog $$FOO
用法:
$ make run FOO="the dog kicked the cat"
./prog the dog kicked the cat
要么:
$ FOO="the dog kicked the cat" make run
./prog the dog kicked the cat
11 回答
对于标准make,您可以通过定义这样的宏来传递参数
然后像这样使用它们
参考资料make微软的NMake
我不知道如何完全按照您的意愿行事,但解决方法可能是:
然后:
这个问题差不多有三年了,但无论如何......
如果你正在使用GNU make,这很容易做到 . 唯一的问题是
make
会将命令行中的非选项参数解释为目标 . 解决方案是将它们变成无所事事的目标,所以make
不会抱怨:运行这个给出:
您可以将变量传递给Makefile,如下所示:
用法:
要么:
或者使用Beta提供的解决方案:
用法:
TL; DR不会尝试这样做
而是创建脚本:
这样做:
回答所述问题:
你可以在食谱中使用一个变量
然后将变量赋值作为参数传递给make
这将执行
./prog arg
.但要小心陷阱 . 我将详细说明这种方法的缺陷以及其他方法 .
回答问题背后的假设意图:
假设:您希望使用某些参数运行
prog
,但必要时在运行之前重建它 .答案:创建一个脚本,必要时重建然后用args运行prog
这个脚本使意图非常明确 . 它使用make来做它有用的东西:建筑 . 它使用shell脚本来执行它的优点:批处理 .
调用语法现在几乎完全相同:
相比于:
此外,您可以使用shell脚本的完全灵活性和表现力来执行您可能需要的任何其他操作,而无需makefile的所有注意事项 .
背景:
make不是为运行目标而设计的,而是将参数传递给该目标 . 命令行上的所有参数都被解释为目标(a.k.a.target),选项或变量赋值 .
所以如果你运行这个:
make会将
run
,foo
和bar
解释为目标(目标),以根据他们的食谱进行更新 .--wat
作为make的选项 . 和var=arg
作为变量赋值 .有关详细信息,请参阅:https://www.gnu.org/software/make/manual/html_node/Goals.html#Goals
术语见:https://www.gnu.org/software/make/manual/html_node/Rule-Introduction.html#Rule-Introduction
关于变量赋值方法以及我推荐它的原因
和食谱中的变量
这是将参数传递给配方的最简单直接的方法 . 但是虽然它可以用来运行带有参数的程序,但它当然不是设计成以这种方式使用的 . 见https://www.gnu.org/software/make/manual/html_node/Overriding.html#Overriding
在我看来,这有一个很大的缺点:你想要做的是用参数
arg
运行prog
. 但不是写作:你在写:
当尝试传递包含空格的多个参数或参数时,这会变得更加尴尬:
相比于:
为了记录这是我的
prog
看起来像:请注意,当您将
$(var)
放在makefile中的引号中时:然后
prog
将始终只有一个参数:所有这些都是我推荐这条路线的原因 .
为了完整性,这里有一些“传递参数来运行”的其他方法 .
方法1:
超短解释:从目标列表中筛选出当前目标 . 创建捕获所有目标(
%
),它不会无声地忽略其他目标 .方法2:
超短解释:如果目标是
run
,则删除第一个目标,并使用eval
为剩余目标创建不执行任何目标 .为了更深入的解释研究制作手册:https://www.gnu.org/software/make/manual/html_node/index.html
方法1的问题:
以破折号开头的
解决方法
run
(等于目标)它也将被删除将运行
./prog foo bar
而不是./prog foo bar run
方法2可能的解决方法
将运行
./prog foo bar clean
,但也是目标clean
的配方(假设它存在) .方法2可能的解决方法
没有解决方法
只会默默地忽略
celan
.解决方法是让一切都变得冗长 . 所以你看看会发生什么 . 但这会给合法输出带来很多噪音 .
方法2的问题:
没有我知道的解决方法
没有解决方法
eval
试图创建不做任何目标 .解决方法:创建全局捕获所有目标,如上所述 . 如上所述,它将再次默默地忽略错误的合法目标 .
eval
在运行时修改makefile . 在可读性和可调试性以及Principle of least astonishment方面你会走多远 .解决方法:不要这样做!! 1而是编写一个运行make的shell脚本,然后运行
prog
.我只测试过使用gnu make . 其他品牌可能会有不同的行为 .
TL; DR不会尝试这样做
而是创建脚本:
这样做:
不 . 查看GNU make手册页的语法
你可以指定多个目标,因此'不'(至少没有你指定的确切方式) .
这是另一个可以帮助解决其中一些用例的解决方案:
换句话说,选择一些前缀(在这种情况下为
test-
),然后将目标名称直接传递给程序/运行器 . 我想如果涉及一些可以将目标名称解包为对底层程序有用的东西的转子脚本,这大部分都是有用的 .您可以在命令行中显式提取每个第n个参数 . 为此,您可以使用变量MAKECMDGOALS,它保存给予'make'的命令行参数列表,它将其解释为目标列表 . 如果要提取第n个参数,可以将该变量与“word”函数结合使用,例如,如果需要第二个参数,可以将其存储在变量中,如下所示:
对此并不感到骄傲,但我不想传递环境变量,所以我颠倒了运行canned命令的方式:
这将打印您要运行的命令,因此只需在子shell中进行评估:
anon ,
run: ./prog
看起来有点奇怪,因为正确的部分应该是目标,所以run: prog
看起来更好 .我建议简单地说:
我想补充说,可以传递参数:
作为参数:
make arg1="asdf" run
或被定义为环境:
arg1="asdf" make run
这是我的例子 . 请注意,我使用Dev-Cpp附带的mingw32-make.exe在Windows 7下编写 . (我有c:\ Windows \ System32 \ make.bat,所以命令仍称为“make” . )
用于定期清洁:
用于在mydir /中清理和创建备份的用法: