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
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
相关文章推荐
- linux source命令 http://blog.chinaunix.net/uid-26620753-id-3088545.html
- socket TCP协议 http://blog.chinaunix.net/uid-22488454-id-3059636.html
- 进程0 进程1 http://blog.chinaunix.net/uid-26874138-id-3183711.html
- curl 转自 http://blog.chinaunix.net/uid-22655387-id-3283161.html
- http://blog.chinaunix.net/uid-25082381-id-3242162.html
- fd_set具体是怎样实现的 http://blog.chinaunix.net/uid-20680966-id-1896524.html
- 内核线程 http://blog.chinaunix.net/uid-24467128-id-3246495.html
- C语言 字符串处理函数 转自 http://blog.chinaunix.net/uid-25885064-id-3175049.html
- 经典makefile例子 http://blog.chinaunix.net/uid-25100840-id-2047826.html
- Android Studio apk 打包流程(转)http://blog.chinaunix.net/uid-26000296-id-5567890.html
- (转)一篇图片处理优化思路 原文地址http://blog.chinaunix.net/uid-20806919-id-132246.html
- http://blog.chinaunix.net/uid-21222282-id-3244532.html
- 孤儿进程组 http://blog.chinaunix.net/uid-27767798-id-3711413.html
- 网卡多队列-转载原文地址:http://blog.chinaunix.net/uid-24830931-id-3352000.html
- http://blog.chinaunix.net/uid-20569459-id-335214.html
- http://blog.chinaunix.net/uid-25547034-id-3155778.html
- vim 颜色设置(转http://blog.chinaunix.net/uid-24929997-id-3065936.html)
- 网卡RSS功能--转载原文地址:http://blog.chinaunix.net/uid-24830931-id-3352000.html
- http://blog.chinaunix.net/uid-20484604-id-1941290.html
- Iptables详解(文章来源于http://blog.chinaunix.net/uid-22780578-id-3346350.html)