使用makefile运行二进制文件

时间:2015-07-29 19:28:33

标签: makefile

从我拥有的所有目标中,我需要一个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

如果可能的话。

1 个答案:

答案 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
相反,但我完全不确定为什么要随手。