杂谈make自动化编译

Fromhttp://www.cnblogs.com/strugglever/

make工作原理

关键思想:建立依赖关系树,递归地用依赖文件去更新目标文件,以使整个树最新,也就是所谓的牵一发而动全身。

具体规则

对于某个模式规则,

1.若目标不存在:

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

posted on 2011-07-22 00:58  strugglEver  阅读(528)  评论(0)    收藏  举报