首先说说本次嵌套执行makefile文件的目的:只需make根目录下的makefile文件,便可编译全部c文件,包括子目录下的。php
意义:自动化编译行为,之后编译本身的c文件时可把这些makefile文件直接复制到相应目录便可方便编译出全部文件。这些makefile文件是通用的,只需根据本身的工程状况改动少量内容便可。下面会说。shell
整体思路是:把目标文件放在debug文件夹下的obj目录下,把最终的二进制文件放在debug文件夹下的bin目录下;如何递归编译全部除了debug目录下的makefile文件呢:得到当前目录下的全部子目录,执行子目录下的makefile文件;获取当前目录下的全部c文件,编译c文件并放到指定的目标文件夹下。最后再执行debug目录下的makefile文件生成bin文件。ubuntu
注意:除了debug文件夹比较特殊外,其余的子目录下都须要有Makefile文件,并且这些Makefile是相同的,除了根目录下的makefile文件有些不一样外。即除了bin和obj目录之外的其余目录都须要Makefile文件,即便目录下没有c文件或者其余目录。app
过程:首先在根目录下新建一个debug文件夹,debug文件夹下有bin目录和obj目录和一个Makefile文件,结构以下图。(这个debug文件里的makefile文件须要最后执行)(tree工具须要本身安装的,ubuntu下直接输入sudo apt-get install tree便可,但有时可能须要先sudo apt-get update才行)工具
整个目录结果以下图:google
而后在根目录下新建Makefile文件,根目录下也可能会有c文件,故也需处理根目录下的c文件,内容以下:spa
#设置编译器 CC=gcc #debug文件夹里的makefile文件须要最后执行,因此这里须要执行的子目录要排除debug文件夹,这里使用awk排除了debug文件夹,读取剩下的文件夹 SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "debug") print $$9}') #无需下一行的注释代码,由于咱们已经知道debug里的makefile是最后执行的,因此最后直接去debug目录下执行指定的makefile文件就行,具体下面有注释 #DEBUG=$(shell ls -l | grep ^d | awk '{if($$9 == "debug") print $$9}') #记住当前工程的根目录路径 ROOT_DIR=$(shell pwd) #最终bin文件的名字,能够更改成本身须要的 BIN=myapp #目标文件所在的目录 OBJS_DIR=debug/obj #bin文件所在的目录 BIN_DIR=debug/bin #获取当前目录下的c文件集,放在变量CUR_SOURCE中 CUR_SOURCE=${wildcard *.c} #将对应的c文件名转为o文件后放在下面的CUR_OBJS变量中 CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)} #将如下变量导出到子shell中,本次至关于导出到子目录下的makefile中 export CC BIN OBJS_DIR BIN_DIR ROOT_DIR #注意这里的顺序,须要先执行SUBDIRS最后才能是DEBUG all:$(SUBDIRS) $(CUR_OBJS) DEBUG #递归执行子目录下的makefile文件,这是递归执行的关键 $(SUBDIRS):ECHO make -C $@ DEBUG:ECHO #直接去debug目录下执行makefile文件 make -C debug ECHO: @echo $(SUBDIRS) #将c文件编译为o文件,并放在指定放置目标文件的目录中即OBJS_DIR $(CUR_OBJS):%.o:%.c $(CC) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/$@ CLEAN: @rm $(OBJS_DIR)/*.o @rm -rf $(BIN_DIR)/*
上面的注释很详细了,具体的命令若是不清楚,本身能够google一下,譬如:wildcard patsubst awk等.net
读者能够根据本身的须要更改本身的debug目录和目标文件目录和bin文件目录
debug
其余子目录下的Makefile文件的内容以下:code
1 #子目录的Makefile直接读取其子目录就行 2 SUBDIRS=$(shell ls -l | grep ^d | awk '{print $$9}') 3 #如下同根目录下的makefile的相同代码的解释 4 CUR_SOURCE=${wildcard *.c} 5 CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)} 6 all:$(SUBDIRS) $(CUR_OBJS) 7 $(SUBDIRS):ECHO 8 make -C $@ 9 $(CUR_OBJS):%.o:%.c 10 $(CC) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/$@ 11 ECHO: 12 @echo $(SUBDIRS)
debug目录下的Makefile文件以下:
1 OBJS=*.o 2 ODIR=obj 3 $(ROOT_DIR)/$(BIN_DIR)/$(BIN):$(ODIR)/$(OBJS) 4 $(CC) -o $@ $^
最后只需在根目录下,个人是个人根目录makefile目录下,执行make命令便可:
结果目录结果为:
而后执行". debug/bin/myapp"便可;最后能够执行make CLEAN清楚掉全部的目标文件和bin文件。
参考资料为:http://blog.csdn.net/zplove003/article/details/7066595
关于makefile文件的编写,见一下连接:跟我一块儿写makefile和http://wiki.ubuntu.org.cn/index.php?title=%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile&variant=zh-cn