您的位置:首页 > 理论基础 > 计算机网络

http://blog.chinaunix.net/uid-25835268-id-3055356.html--makefile

2013-08-29 13:28 274 查看
http://blog.chinaunix.net/uid-25835268-id-3055356.html

makefile系列 写的很好

一下是一个稍微完整的Makefile文件,文件编译的工程一共有四个模块:array,foo,hello,Main;

头文件在inc中,源码和子Makefile在src目录中。

#主Makefile

#环境变量,目标路径,进入子目录make all clean,总的make all clean,打印完成信息

.PHONY:all clean

MAKE = make

MAKEFLAG = -r

RM = rm

RMFLAG = -rf

#ROOT是上一目录的绝对路径

ROOT = $(realpath ..)

DIR = $(ROOT)/code/foo/src
$(ROOT)/code/hello/src
$(ROOT)/code/array/src
$(ROOT)/code/Main/src

RMS = $(ROOT)/build/exes
$(ROOT)/build/libs

#1.生成的目标与依赖关系集合

#循环 cd make clean

all clean:

@echo "Make $@ begin!"

@set -e ;\

for dir in $(DIR) ;\

do \

cd $$dir && $(MAKE) -r
ROOT=$(ROOT) $@ ;\

done

@set -e ;\

if [ "$(MAKECMDGOALS)" = "clean" ]; \

then $(RM) $(RMFLAG) $(RMS); \

fi

@echo ""

@echo "~) Completed"

@echo ""

#先必须执行完毕所有的子Makefile中的all clean规则,再执行总的all clean规则,这在26行

#在这一点上无论是all clean都一样,故有一致性,可以写在一起

主Makefile

#公有Makefile

.PHONY:all clean

CC = gcc

RM = rm

RMFLAG = -rf

MKDIR = mkdir

AR = ar

ARFLAG = crs

#3.路径

#绝对路径

DIR_EXE = $(ROOT)/build/exes

DIR_LIBS = $(ROOT)/build/libs

#相对路径

DIR_DEPS = deps

DIR_OBJS = objs

DIRS = $(DIR_DEPS) $(DIR_EXE) $(DIR_LIBS) $(DIR_OBJS)

#3**.RMS clean:exe .a .o .dep文件

#每个子Makefile应该清理掉的战场: .o和.dep文件

RMS = $(DIR_DEPS) $(DIR_OBJS)

#2.目标

#EXE =

#LIBS =

ifneq ("$(LIBS)","")

LIBS := $(addprefix $(DIR_LIBS)/,$(LIBS))

RMS += $(LIBS)

endif

ifneq ("$(EXE)","")

EXE := $(addprefix $(DIR_EXE)/,$(EXE))

RMS += $(EXE)

endif

#4.源

SRCS = $(wildcard *.c)

OBJS = $(SRCS:.c=.o)

OBJS := $(addprefix $(DIR_OBJS)/,$(OBJS))

#依赖关系文件加上路径

DEPS = $(SRCS:.c=.dep)

DEPS := $(addprefix $(DIR_DEPS)/,$(DEPS))

#6.LINK_LIBS与INCLUDE_DIRS

#-I *.h在生成.o文件的方法里和依赖关系里面都用到了,一共两处,INCLUDE_DIRS变量在子Makefile中指定

#-l *.a $(LINK_LIBS)与$(DEP_LIBS)

#做出一个libX%的筛选器,找出$(DIR_LIBS)/里面的所有库文件

ifneq ("$(LINK_LIBS)","")

LINK_LIBS := $(strip $(LINK_LIBS))

LINK_LIBS := $(addprefix -l,$(LINK_LIBS))

LIB_ALL := $(notdir $(wildcard $(DIR_LIBS)/*))

LIB_FILTERED := $(addsuffix %, $(addprefix lib,$(LINK_LIBS)))

$(eval DEP_LIBS=$(filter $(LIB_FILTERED),$(LIB_ALL)))

DEP_LIBS := $(addprefix $(DIR_LIBS)/,$(DEP_LIBS))

endif

ifneq ("$(INCLUDE_DIRS)","")

INCLUDE_DIRS := $(strip $(INCLUDE_DIRS))

INCLUDE_DIRS := $(addprefix -I,$(INCLUDE_DIRS))

endif

#5.DEP_DIR_EXE

#目录不存在则新建目录

#使用ifeq [ "$(DEP_DIR_EXE)","" ],ifeq [ "$(DEP_DIR_EXE" = "" ]是不行的,每次运行Makefile $(DEP_DIR_EXE)都是空,变量是空与文件夹不存在是两回事

ifeq ("$(wildcard $(DIR_EXE))","")

DEP_DIR_EXE := $(DIR_EXE)

endif

ifeq ("$(wildcard $(DIR_OBJS))","")

DEP_DIR_OBJS := $(DIR_OBJS)

endif

ifeq ("$(wildcard $(DIR_LIBS))","")

DEP_DIR_LIBS := $(DIR_LIBS)

endif

ifeq ("$(wildcard $(DIR_DEPS))","")

DEP_DIR_DEPS := $(DIR_DEPS)

endif

#1.生成关系目标依赖

#include与mkdir

#all与DEP_LIBS

all:$(EXE) $(LIBS)

ifneq ($(MAKECMDGOALS),clean)

include $(DEPS)

endif

$(DIRS):

$(MKDIR) $@

$(EXE):$(DEP_DIR_EXE) $(OBJS) $(DEP_LIBS)

$(CC) -L $(DIR_LIBS) -o $@ $(filter %.o,$^) $(LINK_LIBS)

$(DIR_OBJS)/%.o:$(DEP_DIR_OBJS) %.c

$(CC) $(INCLUDE_DIRS) -o $@ -c $(filter %.c,$^)

$(LIBS):$(DEP_DIR_LIBS) $(OBJS)

$(AR) $(ARFLAG) $@ $(filter %.o,$^)

#7.dep依赖关系规则,以便include生成,dep文件

$(DIR_DEPS)/%.dep:$(DEP_DIR_DEPS) %.c

@echo "Creating $@ ..."

@set -e ; \

$(RM) $(RMFLAG) $@.tmp ; \

$(CC) $(INCLUDE_DIRS) -E -MM $(filter %.c,$^) > $@.tmp ; \

sed 's,\(.*\)\.o[ :]*,objs/\1.o $@: ,g' < $@.tmp > $@ ; \

$(RM) $(RMFLAG) $@.tmp

#8.clean

clean:

$(RM) $(RMFLAG) $(RMS)

公有Makefile

#子Makefile模板

#子目标 .h 库 包含公有Makefile

EXE =

LIBS = libarray.a

INCLUDE_DIRS = $(ROOT)/code/array/inc

LINK_LIBS =

include $(ROOT)/build/MakefileRule

子Makefilearray模块

#子Makefile模板

#子目标 .h 库 包含公有Makefile

EXE =

LIBS = libfoo.a

INCLUDE_DIRS = $(ROOT)/code/foo/inc

LINK_LIBS =

include $(ROOT)/build/MakefileRule

[align=center]子Makefilefoo模块[/align]

#子Makefile模板

#子目标 .h 库 包含公有Makefile

#ROOT = /home/qq/learning/MakefileModel/

EXE =

LIBS = libhello.a

INCLUDE_DIRS = $(ROOT)/code/hello/inc

LINK_LIBS =

include $(ROOT)/build/MakefileRule

[align=center]子Makefilehello模块[/align]

#子Makefile模板

#子目标 .h 库 包含公有Makefile

EXE = complicated

LIBS =

INCLUDE_DIRS = $(ROOT)/code/array/inc
$(ROOT)/code/foo/inc
$(ROOT)/code/hello/inc

LINK_LIBS = array foo hello

include $(ROOT)/build/MakefileRule
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐