简单的Makefile

#Makefile小入门

要在Linux环境写自己的程序就需要自己写Makefile,远不如windows下各种IDE来的方便。

那就尝试写一个不要太麻烦的Makefile完成整个编译任务。

写makefile就像做菜一样,形式如下:

配方:材料 | 前置配方:
		制作步骤1
		制作步骤2
		。。。

思路是这样的,如果是移植的软件包,放在一个目录下,例如littlevgl,自己码的程序放在另一个目录下,分开放。
先 arm-linux-gnueabihf-gcc -c -o ???.o ???.c ,进行 .c 编译成 .o 文件,按指定目录存放起来 ;
再 arm-linux-gnueabihf-gcc -o APP *.o ,把.o文件链接成执行文件。

按目录编写对应的makefile 规则:

举个例子:

列出需要的变量
LVGL_INC_DIR :=        					#用来存放头文件的全路径
LVGL_SRC_DIR :=							#用来存放主目录的路径
LVGL_SRC_SUBDIRS :=						#用来存放源文件目录的路径
LVGL_CFILES :=							#用来存放源文件的文件名
LVGL_CFILES_PATH :=						#用来存放源文件的全路径
#LVGL_OBJS :=							#用来存放编译后的.o文件名
#LVGL_OBJS_PATH:=						#用来存放编译后的.o文件全路径
LVGL_OUTPUTDIR := 						#设定输出文件的目录
LVGL_LIB_NAME :=						#设定输出库文件名
初始化变量:
这部分都需要手工填写的:
LVGL_LIB_NAME = lvgl_lib.a  
LVGL_OUTPUTDIR = ./$(OUTPUTDIR)/LVGL_OUT
LVGL_SRC_DIR =  ./lvgl/src
LVGL_SRC_SUBDIRS +=  $(LVGL_SRC_DIR)
LVGL_SRC_SUBDIRS += $(foreach dir, $(shell ls -l $(LVGL_SRC_DIR) | grep ^d | awk '{print $$9}'), $(LVGL_SRC_DIR)/$(dir))
接下来的是自动处理的配方:
先是扫描所有的C文件,用到了makefile 的  $(foreach )  $(shell ) ,shell 命令的 ls  、awk 、 grep,及管道 :
#C文件名
LVGL_CFILES += $(foreach dir ,$(LVGL_SRC_SUBDIRS) ,  \
				$(foreach cfile ,$(shell ls -l $(dir)|awk '{print $$9}'|grep "\.c$$"  ), $(cfile)) \
				)
#C文件全路径
LVGL_CFILES_PATH   = $(foreach dir ,$(LVGL_SRC_SUBDIRS) ,  \
				$(foreach cfile ,$(shell ls -l $(dir)| awk '{print $$9}'|grep "\.c$$" ), $(dir)/$(cfile)) \
				)

处理头文件路径,在路径前添加 -I :
#头文件路径
LVGL_INC_DIR = $(foreach dir , $(LVGL_SRC_SUBDIRS) ,  -I $(dir))
LVGL_INC_DIR += -I ./lvgl

输出路径,用到了shell命令的 mkdir :
#新建输出路径
$(LVGL_OUTPUTDIR):
	mkdir $(LVGL_OUTPUTDIR)

制作.o文件,一个.c文件对应一个.o文件,对应输出目录不存在.o文件或者.c文件修改日期大于.o文件,则重新制作.o文件;用到了 shell 的 if  、 for 、 stat 、xargs等:
#制作.o文件	
LVGL_OBJ_MAKE:$(LVGL_CFILES) $(LVGL_OUTPUTDIR)
	for s in `echo $(LVGL_CFILES_PATH)|cut -d' ' -f 1-`;	do\
		 if  [   ! -f   `echo $$s|awk '{gsub(/\//," ")}{print $$NF}'|awk '{gsub(/.c/,"")}{printf"%s/%s.o","$(LVGL_OUTPUTDIR)",$$0}'`   ]   \
		 ||   [  `stat -c %Y $$s`  -gt `echo $$s|awk '{gsub(/\//," ")}{print $$NF}'|awk '{gsub(/.c/,"")}{printf"%s/%s.o\n","$(LVGL_OUTPUTDIR)",$$0}'|xargs stat -c %Y`   ]    \
		 ;then \
		 echo "\033[36m  process $$s;  \033[0m" \
		 #rm  -f $(LVGL_OUTPUTDIR)/`echo $$s|awk '{gsub(/\//," ")}{print $$NF}'|awk '{gsub(/.c/,"")}{print $$0}'`.o ;\
		 $(CC) $(CFLAGS)   $(LVGL_INC_DIR) -c -o $(LVGL_OUTPUTDIR)/`echo $$s|awk '{gsub(/\//," ")}{print $$NF}'|awk '{gsub(/.c/,"")}{print $$0}'`.o $$s   ; \
		 fi \
	done
	
.o文件名及路径处理 ,makefile 中 配方前置条件   “ 配方:材料 | 前置配方  ” :	
#.o文件名
LVGL_OBJS = $(LVGL_CFILES:.c=.o)
LVGL_OBJS_PATH =$(foreach  f ,   $(shell  ls -l $(LVGL_OUTPUTDIR) |awk '{print $$9}'|grep "\.o$$" ) ,$(LVGL_OUTPUTDIR)/$(f)) 
$(LVGL_OBJS_PATH):|LVGL_OBJ_MAKE

#制作 .a库文件
$(LVGL_LIB_NAME): 
	ar rcs  $(LVGL_LIB_NAME) `ls -l $(LVGL_OUTPUTDIR)|grep ".o$$"|awk '{printf"%s/%s ","$(LVGL_OUTPUTDIR)",$$9}'`


还需要一个清除的配方 ,使用shell 的 rm :
LVGL_LIB_CLEAN:
	rm -r $(LVGL_OUTPUTDIR)
每个目录按法泡制 ,在最后:
X : | APP_OBJ_MAKE LVGL_OBJ_MAKE 
	 $(CC) $(LDFLAGS) -o lvglapp 	$(APP_OBJS_PATH)  $(LVGL_OBJS_PATH) 
	rm -f *.o

执行 make X ,搞定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值