你能在 GNU 的 make 中包装每个命令吗?

问题描述 投票:0回答:3

我想在 make 文件中的每个 shell 命令上注入一个透明的包装命令。类似于

time
shell 命令。 (但是,不是
time
命令。这是一个完全不同的命令。)

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

bash makefile gnu-make
3个回答
4
投票

有点。您可以告诉 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

这是一个完整的、有效的 shell 包装示例:

#!/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

1
投票

我已经做了一些事情,比如修改 Makefile 中的 PATH 环境变量,以便执行一个目录,其中我的脚本链接到我想要包装的所有名称的 bin,而不是实际的 bin。然后,脚本将查看它是如何被调用的,并使用包装的命令执行实际的 bin。

即。

exec time "$0" "$@"

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

我听从吉尔斯的回答。这是比我更好的答案。


0
投票

GNU

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

$SHELL -c <command>

您无法让 make 不放入

-c
,因为大多数 shell 都需要这样做。
-c
作为第一个参数 (
$1
) 传递,
<command>
作为单个参数字符串作为第二个参数 (
$2
) 传递。

您可以编写自己的 shell 包装器,在前面添加您想要的命令,同时考虑到

-c
:

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

这将导致

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

© www.soinside.com 2019 - 2024. All rights reserved.