How to run pre- and post-recipes for every target using GNU Make?

家住魔仙堡 提交于 2019-11-28 00:56:36

问题


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.


回答1:


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



回答2:


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


来源:https://stackoverflow.com/questions/37952098/how-to-run-pre-and-post-recipes-for-every-target-using-gnu-make

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!