问题
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 1to the end of each command, or run the real shell with the-eoption.
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