如何避免重复命令,例如目标规则中的 cd?

How can I avoid repetitive commands, such as cd in a target rule?

在我的 makefile 中有许多 cd $(d) 命令,一个用于目标的每个简单命令。 有什么方法可以减少 cd $(d) 命令的数量吗?

all:
    cd $(d); command1
    cd $(d); command2
    cd $(d); command3
    cd $(d); command4
    cd $(d); command5

您可以使用续行并仅传递 shell 一行,其中命令以分号分隔:

all:
    cd $(d); \
    command1; \
    command2; \
    command3; \
    command4; \
    command5

甚至

all:
    cd $(d); command1; command2; command3; command4; command5

递归生成?

.PHONY: all
all: ; ${MAKE} -C $d all-in-d

PHONY: all-in-d
all-in-d:
    command1
    command2
    command3
    command4

首先使用 shell CD 到 $d 的脚本作为 make${SHELL}.

.PHONY: all
all: SHELL := ./cd-to-d
all: .SHELLFLAGS :=
all:
    command1
    command2
    command3
    command4

我们使用特定于目标的变量,以免干扰 makefile 中的其他命令。

不过,如果我们添加规则来创建 cd-to-d,它会变得有点混乱。

cd-to-d: SHELL := ${SHELL}
cd-to-d: .SHELLFLAGS := ${.SHELLFLAGS}
cd-to-d:
    echo '#!/bin/bash' >$@-tmp
    echo 'cd "$d"' >>$@-tmp
    echo 'exec "$$@"' >>$@-tmp
    chmod a+x $@-tmp
    mv $@-tmp $@

.PHONY: all
all: SHELL := ./cd-to-d
all: .SHELLFLAGS :=
all: cd-to-d
all:
    command1
    command2
    command3
    command4

为什么所有 $@-tmp 噪音?如果我们在创建 cd-to-d 时遇到错误,我们不想留下一个旧的。您可以改用 .DELETE_ON_ERROR:(我总是这样做)。

为什么 SHELL := ${SHELL} 噪音?当 makecd-to-d 构建为 all 的依赖项时,它将继承 all 的目标特定定义。我们需要取消那些与更改食谱有关的内容 shell.

嗯。