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

时间:2016-06-21 18:35:36

标签: c++ makefile gnu-make

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

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

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

2 个答案:

答案 0 :(得分:4)

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

此外,如果您使用多行配方,则必须启用.ONESHELL模式。

  

警告:在此模式下,失败的命令(最后一个除外)不会失败   规则,因此您必须使用&&加入命令,或追加   || exit 1到每个命令的末尾,或者使用-e运行真实的shell   选项。

示例:

<强>预后壳

#!/bin/bash

preaction()
{
    echo "Pre-action"
}

postaction()
{
    echo "Post-action"
}

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

<强>生成文件

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

答案 1 :(得分:3)

您可以在拨打电话的同一个文件中使用$(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