从我拥有的所有目标中,我需要一个run
程序。
从命令行,我会说:
$ make main_run.err
或
$ make main_time.err
如果它特定于某个程序,我会编写规则:
main_run.err main_time.err: main.x
@echo ------------------- $(DEFSYM) Running ---------------------
/usr/bin/time -p -o main_time.err ./main.x > main_run.err || true
@echo -----------------------------------------------------------
现在,如何概括它?
我的第一次尝试是:
命令行:
$ make run main.x
规则:
run: $(filter-out $@,$(MAKECMDGOALS))
@echo --------------- $(DEFSYM) Running -----------------
/usr/bin/time -p -o time.err ./$< > run.err || true
@echo ---------------------------------------------------
这给了我一些奇怪的错误:
make: Circular run <- run dependency dropped.
------------- BUILD_150729_162018 Running -----------------
/usr/bin/time -p -o time.err ./main.x > run.err || true
-----------------------------------------------------------
make: 'main.x' is up to date.
我的第二次也是最好的尝试,我要求帮助的人(除非有另一种更容易的方式),是:
%_run.err %_time.err: %.x
@echo ------------------- $(DEFSYM) Running ---------------------
/usr/bin/time -p -o $@_time.err ./$< > $@_run.err || true
@echo -----------------------------------------------------------
这几乎没问题!但文件名错误:
--------------- BUILD_150729_162239 Running -----------------
/usr/bin/time -p -o main_run.err_time.err ./main.x > main_run.err_run.err || true
-------------------------------------------------------------
命令行不好:
$ make main_run.err
我知道我可以使用:
$ make run x=main
定义变量$(x)
,但我更喜欢:
$ make run main.x
如果可能的话。
答案 0 :(得分:1)
这次尝试:
%_run.err %_time.err: %.x
@echo ------------------- $(DEFSYM) Running ---------------------
/usr/bin/time -p -o $@_time.err ./$< > $@_run.err || true
@echo -----------------------------------------------------------
这是正确的想法。您只需调整正在使用的automatic variables以匹配模式规则的更改。
具体而言,您需要$*
(词干)变量而不是$@
(目标)变量。
从手册:
$ @
规则目标的文件名。如果目标是归档成员,则'$ @'是归档文件的名称。在具有多个目标的模式规则中(请参阅模式规则简介),'$ @'是导致规则配方运行的任何目标的名称。
$ *
隐式规则匹配的词干(请参阅模式匹配)。如果目标是dir / a.foo.b并且目标模式是。%。b那么干是dir / foo。词干对于构造相关文件的名称很有用。
在静态模式规则中,词干是文件名的一部分,与目标模式中的'%'匹配。
所以你最终得到:
%_run.err %_time.err: %.x
@echo ------------------- $(DEFSYM) Running ---------------------
/usr/bin/time -p -o $*_time.err ./$< > $*_run.err || true
@echo -----------------------------------------------------------
原始原文:
main_run.err main_time.err: main.x
@echo ------------------- $(DEFSYM) Running ---------------------
/usr/bin/time -p -o main_time.err ./main.x > main_run.err || true
@echo -----------------------------------------------------------
不正确,因为它确实不告诉make两个文件都是由目标的一次运行创建的,因此如果你指定了,那么make可能会运行两次 {{ 1}}和main_run.err
在同一时间。模式规则版本确实告诉make有关该事实(请参阅Pattern Rule Examples上手册部分的最后一段以获得对此的解释)。
要使初始命令行更漂亮,可以添加:
main_time.err
这将允许您运行.PHONY: run_%
run_%: %_run.err %_time.err
。
...
我这么说,但是在一个不起作用的快速模拟测试中它需要:
make run_main
相反,但我完全不确定为什么要随手。