接上一个练习:
//test.cpp 二叉树类测试
#include "tree.h"
#include <iostream>
using namespace std;
int main(void)
{
T array[]={27,12,42,9,36,1,28,22,19,70,90,28,21,34};
CBinaryTree a(array, sizeof(array)/sizeof(T));
a.TraverseByBehindOrder(a.GetTreeRoot());
cout<<"start test tree!"<<a.TreeDepth( a.GetTreeRoot())<<endl;
a.PrintTree();
}
//Makefile ,参考了网上万能Makefile的写法,加自己理解注释:
EXECUTABLE := main # 可执行文件名
LIBDIR:= # 静态库目录
LIBS := # 静态库文件名
INCLUDES:=. # 头文件目录
SRCDIR:= # 除了当前目录外,其他的源代码文件目录
# # Now alter any implicit rules' variables if you like, e.g.:
CC:=g++
CFLAGS := -g -Wall -O3 #-g 添加gdb调试信息; -Wall 提示warning信息; -O3 表示第3级优化.
CPPFLAGS := $(CFLAGS)
CPPFLAGS += $(addprefix -I,$(INCLUDES))
CPPFLAGS += -MMD
# The next bit checks to see whether rm is in your djgpp bin
# directory; if not it uses del instead, but this can cause (harmless)
# `File not found' error messages. If you are not using DOS at all,
# set the variable to something which will unquestioningly remove
# files.
RM-F := rm -f
# # You shouldn't need to change anything below this point.
SRCS := $(wildcard *.cpp) $(wildcard $(addsuffix /*.cpp, $(SRCDIR)))#表示列举当前目录中扩展名为.cpp的所有文件,然后赋值给变量SRCS
OBJS := $(patsubst %.cpp,%.o,$(SRCS))#表示,将$(SRCS)中所有满足模式%.cpp的字符串替换为%.o。
DEPS := $(patsubst %.o,%.d,$(OBJS)) #表示,将$(OBJ)中所有满足模式%.o 的字符串替换为%.d
#$(filter-out $(A),$(B))表示从B中过滤掉A中的内容,返回剩余内容
MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.cpp,$(MISSING_DEPS)))
#.PHONY all deps objs clean veryclean rebuild info 这些都是“伪目标”
.PHONY : all deps objs clean cleanall rebuild info
#all是第一个目标,所以输入make时它被默认执行;all生成或更新所有*.cpp文件对应的*.d文件和*.o文件,
#并链接所有*.o文件生成可执行文件$(EXECUTABLE)。
all: $(EXECUTABLE)
deps : $(DEPS) #deps仅仅生成*.d文件;.d文件是什么文件?它包含了代码文件的依赖信息。
objs : $(OBJS) #objs仅仅生成*.o文件;.o文件是C++代码编译后的中间结果文件,废话
clean :
@$(RM-F) *.o
@$(RM-F) *.d
cleanall: clean
@$(RM-F) $(EXECUTABLE)
#rebuild先调用veryclean清除结果文件,再调用all重新编译和链接
rebuild: veryclean all
ifneq ($(MISSING_DEPS),)
$(MISSING_DEPS) :
@$(RM-F) $(patsubst %.d,%.o,$@)
endif
#$(DEPS)是包含依赖信息的文件,每个源文件对应一个.d文件;-include $(DEPS)表示把这些依赖信息包含进来;
-include $(DEPS)
$(EXECUTABLE) : $(OBJS)
#$(EXECUTABLE)为可执行文件名;$(OBJS)为所有.o文件名;$(CC)在这里是g++;$(addprefix -l,$(LIBS)添加引用库;
$(CC) -o $(EXECUTABLE) $(OBJS) $(addprefix -L,$(LIBDIR)) $(addprefix -l,$(LIBS))
info:
@echo $(SRCS)
@echo $(OBJS)
@echo $(DEPS)
@echo $(MISSING_DEPS)
@echo $(MISSING_DEPS_SOURCES)
# 前面说好的*.d文件和*.o文件是怎么生成的呢?貌似没有命令指出要生成它们呀!请看隐含规则!
# $(EXECUTABLE)依赖于$(OBJS),但makefile中没有指明$(OBJS)依赖于谁,也没指明命令生成它们;
# 这时,make的隐含规则开始起作用;针对$(OBJS)中的每个目标,make自动调用:
# $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
# 依次生成.o文件和.d文件;
# $<表示依赖文件列表的第一个文件名;
# $@表示目标文件名;
# 之所以会生成.d文件,是由于“-MMD”这一编译选项。为g++加上这一选项后,编译器会生成文件依赖信息,并存放至.d文件中。
#
# 每一个.cpp文件相应地生成一个.d文件和一个.o文件?#
# @符号
# 命令行前的@符号表示不回显命令行;
#
# CFLAGS和CPPFLAGS
# 这两者包含编译选项,更详细内容请Google之。
转载于:https://my.oschina.net/mingfu/blog/527527