杂谈make自动化编译
From:http://www.cnblogs.com/strugglever/
make工作原理
关键思想:建立依赖关系树,递归地用依赖文件去更新目标文件,以使整个树最新,也就是所谓的牵一发而动全身。
具体规则:
对于某个模式规则,
1.1且没有依赖文件:执行命令,哪怕有一丝希望也要产生目标。
1.2且有依赖文件:先递归处理其所有依赖的模式规则,再执行命令。
2. 若目标存在:
2.1且没有依赖文件:什么都不做,认为目标是最新的。
2.2且有依赖文件:
先递归处理其所有依赖的模式规则,再比较目标文件和依赖文件。
a. 若没有一个比目标更新:什么都不做,目标已经是最新的。
b. 若至少有一个都比目标更新:执行命令,更新目标文件。
伪目标的作用
与目标的唯一区别:不搜索伪目标,并且认为它不存在。
这个特性将会产生一系列效应,从而有以下这些用途。
用途:
依赖为空:执行shell命令,并且能够避免与文件产生名字冲突,若冲突则会导致命令无法执行
依赖是文件:生成一个或多个终极目标
依赖是伪目标:执行一个或多个伪目标,将以shell循环方式对目录进行的串行化编译转化成并行编译,提高编译效率
文件搜索机制
在vpath指定的目录集下搜索目标文件T或依赖文件P,若在目录D下搜索到,则:
自动化变量$@(表示模式规则中的目标文件)被赋值为不带路径的文件名,T或P;
自动化变量$^(表示模式规则中的依赖文件)被赋值为带路径的文件名,D/T或D/P。
以下是我使用的对多目录下服务器源代码进行编译的makefile文件及相关文件
makefile配置文件makefile.cfg
#common root dirs
#服务器主目录
SERVER_ROOT:=
#make vars
#模式规则中头文件搜索目录集
INCDIRS:=
#模式规则中源文件搜索目录集
SRCDIRS:=
#模式规则中目标文件搜索目录
OBJDIR:=
#带路径的可执行文件名
ELFFILE:=
#g++ options
CFLAGS:=-g –Wall
#编译时头文件搜索目录集
INCLUDES:=
#编译时库文件及其搜索目录集
LIBS:=
makefile文件
include makefile.cfg
vpath %.h $(INCDIRS)
vpath %.cpp $(SRCDIRS)
vpath %.o $(OBJDIR)
SRCFILES:=$(notdir $(shell find $(SRCDIRS) -name *.cpp))
OBJFILES:=$(patsubst %.cpp, %.o, $(SRCFILES))
.PHONY : elf obj clean
elf : $(ELFFILE)
$(ELFFILE) : $(OBJFILES)
$(CXX) $^ -o $@ ${LIBS} $(CFLAGS)
obj : $(OBJFILES)
$(OBJFILES) : %.o : %.cpp
$(CXX) $^ -o $(OBJDIR)/$@ $(INCLUDES) $(CFLAGS) -c
clean :
@$(RM) ${OBJDIR}/* $(ELFFILE)
编译驱动文件build.sh
#!/usr/bin/env bash
if [ $# != 0 ] && [ $# != 1 ];
then
echo -e "usage : \n\t$0(clean and compile)\n\tor\n\t$0 [clean|compile]\n"
exit;
fi
if [ $# == 0 ];
then
make clean && make obj && make elf
elif [ $# == 1 ];
then
if [ $1 == 'clean' ];
then
make clean
elif [ $1 == 'compile' ];
then
make obj && make elf
fi
fi
浙公网安备 33010602011771号