北京市城市建设档案馆网站,西安网站制作价格,西安seo代理计费,高端网站特色文章目录1、规划makefile编写2、makefile文件2.1、根目录下common.mk2.2、config.mk2.3、根目录makefile2.4、其他目录下1、规划makefile编写
a、根目录下放三个文件#xff1a; 1、makefile#xff1a;是咱们编译项目的入口脚本#xff0c;编译项目从这里开始#xff0c;…
文章目录1、规划makefile编写2、makefile文件2.1、根目录下common.mk2.2、config.mk2.3、根目录makefile2.4、其他目录下1、规划makefile编写
a、根目录下放三个文件 1、makefile是咱们编译项目的入口脚本编译项目从这里开始起总体控制作用。 2、config.mk配置脚本被makefile包含单独分处理为了应付一些可变的东西。 3、common.mk最核心的编译脚本定义makefile编译规则并且各个子目录中都用到这个来编译.c文件的编译 b、每个子目录下 都有一个叫做makefile的文件每个makefile文件都会包含根目录下的common.mk。 现在不支持目录中嵌套子目录
2、makefile文件
2.1、根目录下common.mk #.PHONY:all clean ifeq ($(DEBUG),true)
#-g是生成调试信息。GNU调试器可以利用该信息
CC g -stdc11 -g
VERSION debug
else
CC g -stdc11
VERSION release
endif#CC gcc# $(wildcard *.c)表示扫描当前目录下所有.c文件
#SRCS nginx.c ngx_conf.c
SRCS $(wildcard *.cxx)#OBJS nginx.o ngx_conf.o 这么一个一个增加.o太麻烦下行换一种写法把字符串中的.c替换为.o
OBJS $(SRCS:.cxx.o)#把字符串中的.c替换为.d
#DEPS nginx.d ngx_conf.d
DEPS $(SRCS:.cxx.d)#可以指定BIN文件的位置,addprefix是增加前缀函数
#BIN /mnt/hgfs/linux/nginx
BIN : $(addprefix $(BUILD_ROOT)/,$(BIN))#定义存放ojb文件的目录目录统一到一个位置才方便后续链接不然整到各个子目录去不好链接
#注意下边这个字符串末尾不要有空格等否则会语法错误
LINK_OBJ_DIR $(BUILD_ROOT)/app/link_obj
DEP_DIR $(BUILD_ROOT)/app/dep#-p是递归创建目录没有就创建有就不需要创建了
$(shell mkdir -p $(LINK_OBJ_DIR))
$(shell mkdir -p $(DEP_DIR))#我们要把目标文件生成到上述目标文件目录去利用函数addprefix增加个前缀
#处理后形如 /mnt/hgfs/linux/nginx/app/link_obj/ngx_signal2.o /mnt/hgfs/linux/nginx/app/link_obj/ngx_signal.o
# : 在解析阶段直接赋值常量字符串【立即展开】而 在运行阶段实际使用变量时再进行求值【延迟展开】
# /mnt/hgfs/linux/nginx/app/link_obj/nginx.o /mnt/hgfs/linux/nginx/app/link_obj/ngx_conf.o
OBJS : $(addprefix $(LINK_OBJ_DIR)/,$(OBJS))
DEPS : $(addprefix $(DEP_DIR)/,$(DEPS))#找到目录中的所有.o文件编译出来的
LINK_OBJ $(wildcard $(LINK_OBJ_DIR)/*.o)
#因为构建依赖关系时app目录下这个.o文件还没构建出来所以LINK_OBJ是缺少这个.o的我们 要把这个.o文件加进来
LINK_OBJ $(OBJS)#-------------------------------------------------------------------------------------------------------
#make找第一个目标开始执行[每个目标[就是我们要生成的东西]其实都是定义一种依赖关系]目标的格式为
#目标目标依赖【可以省略】
# 要执行的命令【可以省略】
#如下这行会是开始执行的入口执行就找到依赖项$(BIN)去执行了同时这里也依赖了$(DEPS)这样就会生成很多.d文件了
all:$(DEPS) $(OBJS) $(BIN)#这里是诸多.d文件被包含进来每个.d文件里都记录着一个.o文件所依赖哪些.c和.h文件。内容诸如 nginx.o: nginx.c ngx_func.h
#我们做这个的最终目的说白了是即便.h被修改了也要让make重新编译我们的工程否则你修改了.hmake不会重新编译那不行的
#有必要先判断这些文件是否存在不然make可能会报一些.d文件找不到
ifneq ($(wildcard $(DEPS)),) #如果不为空,$(wildcard)是函数【获取匹配模式文件名】这里 用于比较是否为
include $(DEPS)
endif#----------------------------------------------------------------1begin------------------
#$(BIN):$(OBJS)
$(BIN):$(LINK_OBJ)echo ------------------------build $(VERSION) mode--------------------------------!!!#一些变量$目标 $^所有目标依赖
# gcc -o 是生成可执行文件$(CC) -o $ $^ -lpthread#----------------------------------------------------------------1end-------------------#----------------------------------------------------------------2begin-----------------
#%.o:%.c
$(LINK_OBJ_DIR)/%.o:%.cxx
# gcc -c是生成.o目标文件 -I可以指定头文件的路径
#如下不排除有其他字符串所以从其中专门把.c过滤出来
#$(CC) -o $ -c $^$(CC) -I$(INCLUDE_PATH) -o $ -c $(filter %.cxx,$^)
#----------------------------------------------------------------2end-------------------#----------------------------------------------------------------3begin-----------------
#我们现在希望当修改一个.h时也能够让make自动重新编译我们的项目所以我们需要指明让.o依赖于.h文件
#那一个.o依赖于哪些.h文件我们可以用“gcc -MM c程序文件名” 来获得这些依赖信息并重定向保存到.d文件中
#.d文件中的内容可能形如nginx.o: nginx.c ngx_func.h
#%.d:%.c
$(DEP_DIR)/%.d:%.cxx
#gcc -MM $^ $
#.d文件中的内容形如nginx.o: nginx.c ngx_func.h ../signal/ngx_signal.h但现在的问题是我们的.o文件已经放到了专门的目录
# 所以我们要正确指明.o文件路径这样对应的.h,.c修改后make时才能发现这里需要用到sed文本处理工具和一些正则表达式语法不必深究
#gcc -MM $^ | sed s,\(.*\)\.o[ :]*,$(LINK_OBJ_DIR)/\1.o:,g $
#echo 中 -n表示后续追加不换行echo -n $(LINK_OBJ_DIR)/ $
# gcc -MM $^ | sed s/^/$(LINK_OBJ_DIR)/g $
# 表示追加
# gcc -I$(INCLUDE_PATH) -MM $^ $$(CC) -I$(INCLUDE_PATH) -MM $^ $#上行处理后.d文件中内容应该就如/mnt/hgfs/linux/nginx/app/link_obj/nginx.o: nginx.c ngx_func.h ../signal/ngx_signal.h#----------------------------------------------------------------4begin-----------------#----------------------------------------------------------------nbegin-----------------
#clean:
#rm 的-f参数是不提示强制删除
#可能gcc会产生.gch这个优化编译速度文件
# rm -f $(BIN) $(OBJS) $(DEPS) *.gch
#----------------------------------------------------------------nend------------------2.2、config.mk
#定义项目编译的根目录,通过export把某个变量声明为全局的[其他文件中可以用]这里获取当前这个文件所在的路径作为根目录
#BUILD_ROOT /mnt/hgfs/linux/nginx
export BUILD_ROOT $(shell pwd)#定义头文件的路径变量
export INCLUDE_PATH $(BUILD_ROOT)/_include#定义我们要编译的目录
BUILD_DIR $(BUILD_ROOT)/signal/ \$(BUILD_ROOT)/proc/ \$(BUILD_ROOT)/net/ \$(BUILD_ROOT)/misc/ \$(BUILD_ROOT)/logic/ \$(BUILD_ROOT)/app/ #编译时是否生成调试信息。GNU调试器可以利用该信息
#很多调试工具包括Valgrind工具集都会因为这个为true能够输出更多的调试信息
export DEBUG true
2.3、根目录makefile include config.mk
all:
#-C是指定目录
#make -C signal #可执行文件应该放最后
#make -C app #用shell命令for搞shell里边的变量用两个$for dir in $(BUILD_DIR); \do \make -C $$dir; \doneclean:
#-rf删除文件夹强制删除rm -rf app/link_obj app/dep nginxrm -rf signal/*.gch app/*.gch
2.4、其他目录下
#只生成 .d,.o即可
BIN nginx #这个可以保证生成nginx可执行文件
include $(BUILD_ROOT)/common.mk