How to run pre- and post-recipes for every target

2020-02-11 03:10发布

In make, is it possible to define a pre- and post-recipe for every target?

I want to (implicitly) insert the pre-recipe just above the first line of the explicit recipe and then (implicitly) insert the post-recipe after the last line in the explicit recipe.

It would be pretty easy to do it using regular expressions to insert lines but implicit ones would be so much cleaner.

2条回答
爷的心禁止访问
2楼-- · 2020-02-11 03:30

You can create a special helper shell that executes the desired pre- and post- actions before and after its input script and tell make to use that shell for executing the recipes (use the SHELL variable to that end).

Besides, if you are using multiline recipes, you will have to enable the .ONESHELL mode.

Caveat: in this mode a failed command (except the last one) doesn't fail the rule, so you either have to join the commands with &&, or append || exit 1 to the end of each command, or run the real shell with the -e option.

Example:

pre-post-shell

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

Output:

$ make
Pre-action
Hello
Hello again
Post-action
Pre-action
Bye
Post-action
查看更多
你好瞎i
3楼-- · 2020-02-11 03:33

You can have a target that you call using the $(MAKE) command on the same file making the call:

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

This example Makefile will output something like:

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
查看更多
登录 后发表回答