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
可能会导致意外行为。另外两种方法是安全的。