makefile多目录的

来源:互联网 发布:centos安装pptp 编辑:程序博客网 时间:2024/06/06 05:03
这是一个项目的,如果是多个项目。那么cd 项目目录  make 即可(cd $(TREE) && make all)。 make执行的就是目录下面的项目的makefile

下面是两种makefile:
       一种是所有.c的依赖信息在一个文件里;
       一种是每个.c的依赖信息都有一个.d, 一一对应。并且自动根据设置的依赖目录搜索所需的文件,生成依赖






                                                                  所有.c文件的依赖信息在一个文件里
****************************************************************************************************************************************
所有.c的依赖在一个文件里。坏处是比如在一个已知的目录下。增加了一个.c文件。那么直接make。就不会生成此.c的依赖信息,这就是缺点。对此。一个可行的做法是为每个.c生成一个依赖信息。下一部分就是此版本

BIN = test.exe
CC = gcc
INCS = -I"c:/dev-cpp/include"
LIBS = -L"c:/dev-cpp/lib" 
SUBDIRS = config tree
#
#
#maintest.c tree/rbtree.c  多了子目录,那就直接添加 目录/*.c即可   所有的源文件--  .c文件列表
SRCS = $(wildcard *.c ./tree/*.c ./config/*.c)
#
#所有的.o文件列表
OBJS =$(SRCS:.c=.o)

#
#生成依赖信息 -MM是只生成自己的头文件信息,-M 包含了标准库头文件信息。
MAKEDEPEND = gcc -MM    
CFLAGS = $(INCS)
                    
all:$(BIN)

#生成.o的对自己目录中.h .c的依赖信息到当前文件的.depend文件中
.depend:
    $(MAKEDEPEND) $(SRCS) > $@

#先删除依赖信息
#重新生成依赖信息
#这里出现了一个 $(MAKE) 没有定义的变量。这个变量是由 Make 自己定义的,它的值即为自己的位置,方便 Make #递归调用自己。
depend:
    rm .depend
    $(MAKE) .depend

#$(OBJS):%.o :%.c  先用$(OBJS)中的一项,比如foo.o: %.o : %.c  含义为:试着用%.o匹配foo.o。如果成功%就等于foo。如果不成功,
# Make就会警告,然后。给foo.o添加依赖文件foo.c(用foo替换了%.c里的%)
$(OBJS) : %.o:%.c
    $(CC) -c $< -o $@ $(CFLAGS)
#
# $@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。每次$< $@ 代表的值就是列表中的
#
$(BIN) : $(OBJS)
    $(CC) -o $(BIN) $(OBJS) $(LIBS)
# 链接为最终目标


#引入了.o文件对.c和.h的依赖情况。以后.h被修改也会重新生成,可看看.depend文件内容即知道为何
include .depend    
.PHONY:clean cleanall

#清除所有目标文件以及生成的最终目标文件
clean:            
    rm $(BIN) $(OBJS)
#rm .depend
cleanall:
    rm .depend
    rm $(BIN) $(OBJS)
************************************************************************************************************************************






                                                         对于每个.c文件都单独生成.d依赖信息文件
************************************************************************************************************************************

BIN = test.exe
CC = gcc
#这里只加入库头文件路径及库路径
INCS = -I"c:/dev-cpp/include"
LIBS = -L"c:/dev-cpp/lib" 
SUBDIRS =
#生成依赖信息时的搜索目录,比如到下列目录中搜索一个依赖文件(比如.h文件)
DEFINC = -I"src" -I"src/base/tree" -I"src/base" -I"src/config" -I"src/mem"
#给INCS加上依赖搜索路径,分开写可能会产生不一致情况,而且繁琐
INCS += $(DEFINC)
#
#
#maintest.c tree/rbtree.c  多了子目录,那就直接添加 目录/*.c即可   所有的源文件--  .c文件列表
SRCS = $(wildcard ./*.c ./src/*.c ./src/base/*.c ./src/base/tree/*.c ./src/mem/*.c)

#
#
#所有的.o文件列表
OBJS := $(SRCS:.c=.o)
#
#生成依赖信息 -MM是只生成自己的头文件信息,-M 包含了标准库头文件信息。
#-MT 或 -MQ都可以改变生成的依赖  xxx.o:src/xxx.h 为 src/xxx.o:src/xxx.h 当然。前面的 src/xxx.o需自己指定
#格式为 -MM 输入.c或.cpp  查找依赖路径  -MT或-MQ  生成规则,比如src/xxx.o 
MAKEDEPEND = gcc -MM -MT
CFLAGS += $(INCS)
#
#针对每个.c文件的.d依赖文件列表
DEF = $(SRCS:.c=.d)

all:$(BIN)

#生成.o的对自己目录中.h .c的依赖信息.d文件到.c所在的路径中
#$(DEF)文件是.d文件名列表(含目录),比如tree.d 匹配成功那么%就是tree,然后在尝试%.c,如果成功。则执行规则
# $(<:.c=.o)是获取此.c文件的名字(含路径),然后变为.o比如 src/xxx.o。 以形成如下
# src/xxx.o : src/xxx.c ***.h  ***.h  最前面!!注意。  
# 此做法是每个.d都和生成他的.c在一个目录里,所以需要这样做。
# $(<:.c=.o)之类的 。此时的<相当于变量$< 。切记
# : : :  含义同下
$(DEF) : %.d : %.c
    $(MAKEDEPEND) $(<:.c=.o) $< $(DEFINC) > $@


#先删除依赖信息
#重新生成依赖信息
#这里出现了一个 $(MAKE) 没有定义的变量。这个变量是由 Make 自己定义的,它的值即为自己的位置,方便 Make 递归调用自己。
depend:
    rm $(DEF)
    $(MAKE) $(DEF)

#$(OBJS):%.o :%.c  先用$(OBJS)中的一项,比如foo.o: %.o : %.c  含义为:试着用%.o匹配foo.o。如果成功%就等于foo。如果不成功,
# Make就会警告,然后。给foo.o添加依赖文件foo.c(用foo替换了%.c里的%)
# 也可以不要下面的这个生成规则,因为下面的 include $(DEF)  就隐含了。此处为了明了,易懂。故留着
$(OBJS) : %.o: %.c
    $(CC) -c $< -o $@ $(CFLAGS)

# $@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。每次$< $@ 代表的值就是列表中的
#
$(BIN) : $(OBJS)
    $(CC) -o $(BIN) $(OBJS) $(LIBS)
# 链接为最终目标


#引入了.o文件对.c和.h的依赖情况。以后.h被修改也会重新生成,可看看.d文件内容即知道为何
#引入了依赖就相当于引入了一系列的规则,因为依赖内容例如: 目录/xxx.o:目录/xxx.c 目录/xxx.h 也相当于隐含的引入了生成规则
#故上面不能在出现如: $(OBJS) : $(DEF)之类。切记
include $(DEF)
.PHONY:clean cleanall

#清除所有目标文件以及生成的最终目标文件
clean:            
    rm $(BIN) $(OBJS)
#rm *.d
cleanall:
    rm $(DEF)
    rm $(BIN) $(OBJS)