C++ 如何使用GNU Make为每个目标运行前期和后期配方?

C++ 如何使用GNU Make为每个目标运行前期和后期配方?,c++,makefile,gnu-make,C++,Makefile,Gnu Make,在make中,是否可以为每个目标定义一个前后配方 我想(隐式地)在显式配方的第一行上方插入预配方,然后(隐式地)在显式配方的最后一行之后插入后配方 使用正则表达式插入行非常容易,但隐式表达式会更简洁。您可以在进行调用的同一文件上使用$(MAKE)命令调用一个目标: THIS_FILE:=$(lastword $(MAKEFILE_LIST)) SOURCES:=main.cpp other.cpp OBJECTS:=$(SOURCES:.cpp=.o) OUT:=main .PHONY:

make
中,是否可以为每个目标定义一个前后配方

我想(隐式地)在显式配方的第一行上方插入预配方,然后(隐式地)在显式配方的最后一行之后插入后配方


使用正则表达式插入行非常容易,但隐式表达式会更简洁。

您可以在进行调用的同一文件上使用
$(MAKE)
命令调用一个目标:

THIS_FILE:=$(lastword $(MAKEFILE_LIST))

SOURCES:=main.cpp other.cpp
OBJECTS:=$(SOURCES:.cpp=.o)

OUT:=main

.PHONY: all pre post

all: $(OUT)

$(OUT): $(OBJECTS)
    $(CXX) $(LDFLAGS) -o $(OUT) $(OBJECTS) $(LIBS)

pre:
    @echo "PRE TARGET"

post:
    @echo "POST TARGET"

%.o: pre %.cpp
    $(CXX) $(CXXFLAGS) -c $(lastword $^) -o $@
    @$(MAKE) -f $(THIS_FILE) post
此示例Makefile将输出如下内容:

PRE TARGET
g++ -std=c++11 -O2 -g -c main.cpp -o main.o
POST TARGET
PRE TARGET
g++ -std=c++11 -O2 -g -c other.cpp -o other.o
POST TARGET
g++ -o main main.o other.o

您可以创建一个特殊的助手shell,在输入脚本之前和之后执行所需的前置和后置操作,并告诉
make
使用该shell执行配方(为此使用变量)

此外,如果使用多行配方,则必须启用该模式

警告:在此模式下,失败的命令(最后一个命令除外)不会失败 规则,因此您必须使用
&&&
连接命令,或附加
| |在每个命令结束时退出1
,或者使用
-e
选择权

例如:

壳前壳后壳

#!/bin/bash

preaction()
{
    echo "Pre-action"
}

postaction()
{
    echo "Post-action"
}

preaction && /bin/bash "$@" && postaction
makefile

SHELL=./pre-post-shell

all: Hello Bye

.ONESHELL:

Hello:
    @echo Hello
    echo Hello again

Bye:
    @echo Bye
输出:

$ make
Pre-action
Hello
Hello again
Post-action
Pre-action
Bye
Post-action

您是否希望所有目标都使用相同的预配方?所有目标都有相同的帖子配方?@Beta是的。否则,如果前置和后置对每个目标都是唯一的,那么你最好首先将其粘贴到配方中。我想得没错,我只是想确定这就是你的意思。除了让makefile自己编辑之外,我知道没有办法做你想做的事情。@Beta好的,谢谢你花时间回答。你是说
target:pre-target impl-post-target
是那种东西吗?是的,它有效,但问题要求“隐式规则”这意味着我在
make
中定义了pre-and-post规则以及一些其他标志,然后
make
在执行配方时自动插入pre-and-post规则。正如我在问题中所说的,我知道我可以使用regex有效地将
pre
post
的执行插入到现有的makefile目标中。如果这个选项不存在,那就好了。把它写下来作为答案,我会把它标记为正确的。另外还有一个让我知道如何在现有的makefile中调用特定的目标。如果没有内置选项,我只会在一开始调用
pre
,就像你调用
post
@Adrian一样。我很确定这是唯一一种将规则作为先决条件,将另一个规则作为后决条件的方法。那么helper shell只是一个bash脚本是吗?@Adrian是的,是的,是的(不允许简短评论)使用相同的策略,是否也可以在配方中的每一行之前和/或之后执行静态配方?@Adrian Yes,只是不要使用
。在复杂的bash脚本中使用
-e
可能会导致意外行为。另外两种方法是安全的。