Можете ли вы обернуть каждую команду в GNU make? - PullRequest
2 голосов
/ 14 мая 2011

Я хочу добавить команду прозрачной обертки для каждой команды оболочки в файле make. Что-то вроде команды оболочки time. (Однако не команда time. Это совершенно другая команда.)

Есть ли способ указать какую-нибудь оболочку или декоратор для каждой команды оболочки, которую выдаст gmake?

Ответы [ 3 ]

3 голосов
/ 14 мая 2011

Вид. Вы можете указать make использовать другую оболочку.

SHELL = myshell

, где myshell - это оболочка типа

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

Однако обычный способ сделать это - добавить префикс переменной ко всем вызовам команд. Хотя для подхода SHELL я не вижу ни одного show-stopper, префиксный подход имеет то преимущество, что он более гибкий (вы можете указать разные префиксы для разных команд и переопределить значения префиксов в командной строке) и может быть заметно быстрее.

# 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
1 голос
/ 14 мая 2011

Я не думаю, что есть способ сделать то, что вы хотите в самом GNUMake.

Я сделал такие вещи, как изменил переменную PATH env в Makefile, чтобы каталог сМой сценарий, связанный со всеми именами бинов, которые я хотел обернуть, был выполнен, а не сам бин.Затем скрипт будет смотреть на то, как он вызывался, и исполнять фактическую корзину с помощью обернутой команды.

т.е.exec time "$0" "$@"

В эти дни я обычно просто обновляю цели в самом Makefile.Хранение всех ваших изменений в одном файле обычно лучше IMO, чем управление каталогом ссылок.

Обновление

Я полагаюсь на ответ Жиля.Это лучший ответ, чем мой.

0 голосов
/ 14 мая 2011

Программа, используемая GNU make(1) для запуска команд, определяется переменной SHELL make. Каждая команда будет запускаться как

$SHELL -c <command>

Вы не можете заставить make не вставить -c, поскольку это требуется для большинства оболочек. -c передается как первый аргумент ($1), а <command> передается как строка с одним аргументом как второй аргумент ($2).

Вы можете написать свою собственную оболочку оболочки, которая добавляет команду, которую вы хотите, с учетом -c:

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

Это приведет к запуску time перед каждой командой. Вам нужен eval, поскольку $2 часто не будет отдельной командой и может содержать все виды метасимволов оболочки, которые необходимо расширить или обработать.

...