一、用途:
最终目标是生成山东集抄嵌软集中器上所用的低压集抄应用程序(dyjc)。
二、用法
1、make
生成目标机上用的低压集抄应用程序:dyjc。
2、make clean
清除对象文件(*.o)和依赖文件(*.d)。
3、make veryclean
除了具有make clean的功能外还会清除生成的最终应用程序dyjc。
4、make deps
仅仅生成依赖文件(*.d)。
5、make objs
仅仅生成对象文件(*.o)。
6、make rebuild
重新生成dyjc应用程序。
三、Makefile分析
#********define executable file name**********
#定义可执行程序的名称,需要根据实际情况进行更改
EXECUTABLE := dyjc
#********define shared libs used by the lib,separated by space*********
#使用的共享库列表,以空格分开, 需要根据实际情况更改
LIBS :=stdc++
#define c++ compiler,such as ppc_8xx-g++,g++
#定义使用的C++编译器,例如ppc_8xx-g++,g++等
# 同时用extern导出到环境变量,个人觉得因整个工程只用了一个Makefile,这可以不要
export CC=arm-uclibc-gcc
# 以下这句是多余的,因上面已定义了CC=arm-uclibc-gcc
ifeq ($(CC),cc)
CC=arm-uclibc-gcc
endif
#define path of the shared lib to export
#输出的共享库所在路径
ifeq ($(EXPORTBASEPATH),)
EXPORTBASEPATH=/mnt/hgfs/dyjc
endif
EXPORTPATH:=$(EXPORTBASEPATH)
LIBPATH:=$(EXPORTPATH)/lib
# Now alter any implicit rules' variables if you like, e.g.:
# 现在来改变任何你想改动的隐含规则中的变量,例如
CFLAGS := -Wall -O2 -D ARCH_ARM -D ARCH_ARM7 -D APPLY_GDDYJC
CXXFLAGS := $(CFLAGS)
RM-F := rm -f
# You shouldn't need to change anything below this point.
# 从这里开始,你应该不需要改动任何东西。
#define model rules for c and cpp files
#定义模式规则
#-定义.c文件和.cpp文件生成.o文件的规则,以代替C和CPP文件生成的隐含规则。
# $@: 是%.o中匹配成功的一个目标;
# %<:是相对于$@目标依赖文件列表中的最左边的一个文件。
%.o:%.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
%.o:%.cpp
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
SOURCE_DIRS =include base share conn drule drule/sdjc drule/ftsrule mrule mrule/gb645 mrule/gb645_2007 rrule config config/confuse server server/daemon server/work server/httx server/dbcj server/ppp
# 取当前目录下的C和CPP文件
SOURCE := $(wildcard *.c) $(wildcard *.cpp)
# 取SOURCE_DIRS中所有目录下的C和CPP文件,这样变量SOURCE就包含了所
# 有的C和CPP文件
SOURCE +=$(foreach DIR,$(SOURCE_DIRS),$(wildcard $(DIR)/*.c $(DIR)/*.cpp))
# 取SOURCE_DIRS中所有目录下已存在的OBJ文件,由于SOURCE取了当前目录下
# 的C和CPP文件,而这里没有去查看当前目录,可以说这个ALLOJBS名不符实,即
# 它没有取到所有目录下的OBJ文件,这会导致如果当前目录下有C和CPP文件的话,
# 在“$(RM-F) $(ALLOBJS)”中不能完全清除OBJ文件,没有达到目的。
ALLOBJS :=$(foreach DIR,$(SOURCE_DIRS),$(wildcard $(DIR)/*.o))
# 取SOURCE_DIRS中所有目录下已存在的依赖文件,其它情况和上面分析的一样,
# 不再赘述。
ALLDEPS :=$(foreach DIR,$(SOURCE_DIRS),$(wildcard $(DIR)/*.d))
# 用变量SOURCE通过模式替换来获得OBJ文件,这样获得的是最全的,
# 即和SOURCE一一对应。
OBJS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))
# 由于CDEPS和CPPDEPS这两个变量没有定义,
# 所以CMISSING_DEPS和CPPMISSING_DEPS永远是空。
CMISSING_DEPS := $(filter-out $(wildcard $(CDEPS)),$(CDEPS))
CPPMISSING_DEPS := $(filter-out $(wildcard $(CPPDEPS)),$(CPPDEPS))
# 由于DEPS这个变量没有定义,所以MISSING_DEPS永远是空,
# 因此MISSING_DEPS_SOURCES也永远是空。而且这个MISSING_DEPS_SOURCES
# 还没有使用,是多余的。
MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.c,$(MISSING_DEPS)) $(patsubst %.d,%.cpp,$(MISSING_DEPS)))
# 在预编标志里加入MD标志,是为生成依赖依赖文件所用,但由于MD会把系统头文
# 件也加入到依赖文件里,建议用MMD标志,这个标志只会加入用户头文件到依赖文件里。
CPPFLAGS += -MD
# 伪目标声明,同时everything也默认成了终极目标。
.PHONY : everything deps objs clean veryclean rebuild
everything : $(EXECUTABLE)
# 事实上deps这个目标不可能按预期的目的做事,因为没有生成依赖文件的规则。
deps : $(ALLDEPS)
objs : $(OBJS)
clean :
$(RM-F) *.d
$(RM-F) $(ALLOBJS)
$(RM-F) $(ALLDEPS)
veryclean: clean
$(RM-F) $(EXPORTPATH)/$(EXECUTABLE)
rebuild: veryclean everything
# 由于CMISSING_DEPS和CPPMISSING_DEPS永远为空,以下两个规则不可能会包含
# 进来
ifneq ($(CMISSING_DEPS),)
$(CMISSING_DEPS) :
$(RM-F) $(patsubst %.d,%.o,$@)
$(CC) -o $@ -MM -MMD $(patsubst %.d,%.c,$@)
endif
ifneq ($(CPPMISSING_DEPS),)
$(CPPMISSING_DEPS) :
$(RM-F) $(patsubst %.d,%.o,$@)
$(CC) -o $@ -MM -MMD $(patsubst %.d,%.cpp,$@)
endif
# 包含当前已经存在的依赖文件,为OBJ文件生成提供依赖文件列表。
include $(ALLDEPS)
# 以下是终极目标dyjc程序生成的规则,它依赖于所有的OBJ文件,如果某个OJB文件
# 不存在或比它的依赖文件旧,make会自动调用OBJ的生成规则来生成它。
$(EXECUTABLE) : $(OBJS)
$(CC) -L$(LIBPATH)/ -lm -s -o $(EXPORTPATH)/$(EXECUTABLE) $(OBJS) $(addprefix -l,$(LIBS))
# 以下这句放在这里觉得不妥,它和最终目标的生成没有任何关系。
$(RM-F) *.d
四、以下是我提供的Makefile,仅供参考。
# 个人觉得这样比较简洁一点。
#********define executable file name**********
#定义可执行程序的名称,需要根据实际情况进行更改
EXECUTABLE := dyjc
#********define shared libs used by the lib,separated by space*********
#使用的共享库列表,以空格分开, 需要根据实际情况更改
LIBS :=stdc++
#define c++ compiler,such as ppc_8xx-g++,g++
#定义使用的C++编译器,例如ppc_8xx-g++,g++等
CC=arm-uclibc-gcc
#define path of the shared lib to export
#输出的共享库所在路径
ifeq ($(EXPORTBASEPATH),)
EXPORTBASEPATH=/mnt/hgfs/dyjc
endif
EXPORTPATH:=$(EXPORTBASEPATH)
LIBPATH:=$(EXPORTPATH)/lib
# Now alter any implicit rules' variables if you like, e.g.:
# 现在来改变任何你想改动的隐含规则中的变量,例如
CFLAGS := -Wall -O2 -D ARCH_ARM -D ARCH_ARM7 -D APPLY_GDDYJC
CPPFLAGS += -MMD
RM-F := rm -f
# You shouldn't need to change anything below this point.
# 从这里开始,你应该不需要改动任何东西。
#define model rules for c and cpp files
#定义模式规则
%.o:%.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
%.o:%.cpp
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
SOURCE_DIRS =include base share conn drule drule/sdjc drule/ftsrule mrule mrule/gb645 mrule/gb645_2007 rrule config config/confuse server server/daemon server/work server/httx server/dbcj server/ppp
SOURCE := $(wildcard *.c) $(wildcard *.cpp)
SOURCE += $(foreach DIR,$(SOURCE_DIRS),$(wildcard $(DIR)/*.c $(DIR)/*.cpp))
ALLOBJS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))
EXISTDEPS := $(wildcard *.d)
EXISTDEPS += $(foreach DIR,$(SOURCE_DIRS),$(wildcard $(DIR)/*.d))
.PHONY : everything objs clean veryclean rebuild debug
everything : $(EXECUTABLE)
objs : $(ALLOBJS)
clean :
$(RM-F) $(ALLOBJS)
$(RM-F) $(EXISTDEPS)
veryclean : clean
$(RM-F) $(EXPORTPATH)/$(EXECUTABLE)
rebuild : veryclean everything
debug :
@echo EXISTDEPS=$(EXISTDEPS)
@echo ALLOBJS=$(ALLOBJS)
include $(EXISTDEPS)
$(EXECUTABLE) : $(ALLOBJS)
$(CC) -L$(LIBPATH)/ -lm -s -o $(EXPORTPATH)/$(EXECUTABLE) $(ALLOBJS) $(addprefix -l,$(LIBS))