【问题标题】:Can you wrapper each command in GNU's make?你能在 GNU 的 make 中包装每个命令吗?
【发布时间】:2011-05-13 22:22:28
【问题描述】:

我想在 make 文件中的每个 shell 命令上注入一个透明的包装命令。类似于time shell 命令。 (但是,不是time 命令。这是一个完全不同的命令。)

有没有办法为 gmake 发出的每个 shell 命令指定某种包装器或 decorator

【问题讨论】:

  • 当然,在每个命令中应用包装器。我真的不认为你可以用一个手势来包装所有命令。
  • 您也许可以替换您自己的外壳来进行包装(每行)。每个命令比较棘手,因为这些行是由 shell 解析的,而不是 make。
  • 啊,就是这样,jdigital。 Bash 提供了一种重新转义命令的方法——"$@"。我只需要做类似my_cmd "$@"

标签: bash makefile gnu-make


【解决方案1】:

有点。你可以告诉 make 使用不同的 shell。

SHELL = myshell

myshell 是一个类似包装器的地方

#!/bin/sh
time /bin/sh "$0" "$@"

但是,通常的做法是在所有命令调用前添加一个变量。虽然我看不到 SHELL 方法的任何显示停止器,但前缀方法的优点是它更灵活(您可以为不同的命令指定不同的前缀,并在命令行上覆盖前缀值),并且可能是明显更快。

# Set Q=@ to not display command names
TIME = time
foo:
    $(Q)$(TIME) foo_compiler

下面是一个完整的外壳包装器示例:

#!/bin/bash

RESULTZ=/home/rbroger1/repos/knl/results
if [  "$1" == "-c" ] ; then
    shift
fi

strace -f -o `mktemp $RESULTZ/result_XXXXXXX` -e trace=open,stat64,execve,exit_group,chdir /bin/sh -c "$@"  | awk '{if (match("Process PID=\d+ runs in (64|32) bit",$0) == 0) {print $0}}'

# EOF

【讨论】:

    【解决方案2】:

    我不认为在 GNUMake 本身中可以做你想做的事。

    我已经完成了诸如修改 Makefile 中的 PATH 环境变量之类的操作,因此执行了一个目录,其中我的脚本链接到我想要包装的所有名称的 bin,而不是实际的 bin。然后脚本会查看它是如何被调用的,并使用包装的命令执行实际的 bin。

    即。 exec time "$0" "$@"

    这些天我通常只更新 Makefile 本身中的目标。将所有修改保存在一个文件中通常比管理链接目录更好。

    更新

    我听从 Gilles 的回答。这是一个比我更好的答案。

    【讨论】:

      【解决方案3】:

      GNU make(1) 用来运行命令的程序由 SHELL make 变量指定。它将运行每个命令

      $SHELL -c <command>
      

      你不能不把-c放进去,因为大多数shell都需要这样做。 -c 作为第一个参数 ($1) 传递,&lt;command&gt; 作为单个参数字符串作为第二个参数 ($2) 传递。

      您可以编写自己的 shell 包装器,将-c 考虑在内,将您想要的命令放在前面:

      #!/bin/sh
      eval time "$2"
      

      这将导致time 在每个命令之前运行。您需要eval,因为$2 通常不是单个命令,并且可以包含需要扩展或处理的各种shell 元字符。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-10
        • 2011-03-04
        • 2018-12-22
        • 2020-09-19
        • 1970-01-01
        • 2010-12-24
        • 2013-11-22
        相关资源
        最近更新 更多