2016-06-21 56 views
2

make中,是否可以为每个目标定义预处理和后处理?GNU make - 如何为每个目标运行预处理和后处理

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

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

+0

你想要所有的目标相同的前配方?所有目标都采用相同的后期配方? – Beta

+0

@贝塔是的。否则,如果每个目标的前后都是唯一的,那么你最好先把它粘贴到配方中。 – Adrian

+0

我的想法,我只是想确定这就是你的意思。我知道没有办法做你想做的事情,因为makefile文件本身没有编辑。 – Beta

回答

2

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

此外,如果您正在使用多线食谱,则必须启用.ONESHELL模式。

买者:在此模式下失败的命令(除了最后一个)并没有失败 的规则,让你无论是有&&加入命令,或追加 || exit 1到每年年底命令,或使用-e 选项运行真实shell。

实施例:

预后壳

#!/bin/bash 

preaction() 
{ 
    echo "Pre-action" 
} 

postaction() 
{ 
    echo "Post-action" 
} 

preaction && /bin/bash "[email protected]" && 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 
+0

所以帮手外壳只是一个bash脚本是吗? – Adrian

+0

@Adrian是的,是的,是的(不允许使用简短的评论) – Leon

+0

使用同样的策略,是否可以在配方中的每个LINE之前和/或之后执行静态配方? – Adrian

1

你可以有你调用使用$(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 [email protected] 
    @$(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 
+0

是的,它的工作原理,但问题要求“隐式规则”,这意味着我定义了前后规则,也许还有一些其他的标志在make和make中在执行食谱时插入前后规则。正如我所说的,我知道我可以使用正则表达式有效地将'pre'和'post'的执行插入到现有的makefile目标中。如果这个选项不存在,那很好。把它写成答案,我将其标记为正确。 – Adrian

+0

加一个给我想法在现有的makefile中调用特定的目标。如果没有内置选项,我最终只需要在开始时调用'pre',就像您调用'post'一样# – Adrian

+0

@Adrian我相当确定这是将规则作为必备条件的唯一方法另一个是后备条件。 – CoffeeandCode