第三阶段应用层——1.7 数码相册—电子书(2)—编写通用的Makefile

数码相册——电子书编写通用的Makefile

  • 硬件平台:韦东山嵌入式Linxu开发板(S3C2440.v3)
  • 软件平台:运行于VMware Workstation 12 Player下UbuntuLTS16.04_x64 系统
  • 参考资料:《嵌入式Linux应用开发手册》、《嵌入式Linux应用开发手册第2版》、《gcc中文手册》
  • 开发环境:Linux 3.4.2内核、arm-linux-gcc 4.3.2工具链
  • 源码仓库:https://gitee.com/d_1254436976/Embedded-Linux-Phase-3


一、前言

对于之前的电子书,需要设计一个比较通用的Makefile

  • 目的:当我们修改或在某个目录下添加文件时,修改Makefile时可以方便操作;Makefile可以只预处理编译汇编修改的文件与使用这个文件的文件,之后才进行整体的链接。

二、设计思路

在这里插入图片描述

1、Makefile的分布

分为如下3部分:

  1. 顶层目录的Makefile:定义obj-y来指定根目录下要编进程序去的文件、子目录外,主要是定义工具链、编译参数、链接参数
  2. 顶层目录的Makefile.build:把某个目录及它的所有子目录中、需要编进程序去的文件都编译出来,打包为built-in.o
  3. 各级子目录的Makefile:把当前目录下的.c文件编进程序里。

2、Makefile的使用与修改

2.1 顶层目录

  1. 把顶层MakefileMakefile.build放入程序的顶层目录
  2. 修改顶层Makefile
    2.1 修改工具链
    2.2 修改编译选项、链接选项
    2.3 修改obj-y决定顶层目录下哪些文件、哪些子目录被编进程序
    2.4 修改TARGET,这是用来指定编译出来的程序的名字

2.2 各子目录

在各个子目录下都新建一个Makefile,形式为:
其中subdir1/:代表当前目录下的子目录

obj-y += file1.o
obj-y += file2.o
obj-y += subdir1/
obj-y += subdir2/

三、编写

1、顶层目录

Makefile文件:

# 顶层目录Makefile
#
# 目的:
#	1、每个子目录都会建立一个Makefile,包含当前目录下的.c文件与.h文件
#	2、顶层目录下

# 交叉编译工具链
CROSS_COMPILE = arm-linux-

# 定义一些变量 $(CROSS_COMPILE):取出该变量的值 $(CROSS_COMPILE)gcc-->arm-linux-gcc
AS		= $(CROSS_COMPILE)as		
LD		= $(CROSS_COMPILE)ld
CC		= $(CROSS_COMPILE)gcc
CPP		= $(CC) -E
AR		= $(CROSS_COMPILE)ar
NM		= $(CROSS_COMPILE)nm

STRIP		= $(CROSS_COMPILE)strip
OBJCOPY		= $(CROSS_COMPILE)objcopy
OBJDUMP		= $(CROSS_COMPILE)objdump

# 取出变量的值
export AS LD CC CPP AR NM
export STRIP OBJCOPY OBJDUMP

# := 		简单扩展型变量的值是一次扫描永远使用
# CFLAGS	方便您利用隐含规则指定编译C语言源程序的旗标
# -Wall 	帮助列出所有警告信息
# -02		多优化一些.除了涉及空间和速度交换的优化选项,执行几乎所有的优化工作
# -g		可以认为它是缺省推荐的选项	
CFLAGS := -Wall -O2 -g

# 把当前目录下的include目录下指定为系统目录
# +=		为已经定以过的变量的值追加更多的文本
# -I		指定搜寻包含makefile文件的路径
# $(shell pwd)  执行shell命令的pwd命令,获取执行命令的结果
CFLAGS += -I $(shell pwd)/include

# LDFLAGS	用于调用linker(‘ld’)的编译器的额外标志
# -l		连接库的搜寻目录 -lm调用math库 -lfreetype调用freetype库
LDFLAGS := -lm -lfreetype

# 取出变量的值
export 	CFLAGS LDFLAGS

TOPDIR := $(shell pwd)
export TOPDIR

# TARGET	目标变量
# := 		简单扩展型变量的值是一次扫描永远使用
TARGET := show_file

obj-y += main.o
obj-y += display/
obj-y += draw/
obj-y += encoding/
obj-y += fonts/

# 规则		arm-linux-gcc -lm -lfreetype -o show_file built-in.o
all : 
	make -C ./ -f $(TOPDIR)/Makefile.build
	$(CC) $(LDFLAGS) -o $(TARGET) built-in.o

# 规则		执行make -C 进入当前目录下 使用Makefile.built 进行make
built-in.o:
	make -C ./ -f Makefile.build

# clean 	删除所有make正常创建的文件
# 规则		找到所有make创建出来的.o文件进行删除
#			删除show_file
clean :
	rm -f $(shell find -name "*.o")
	rm -f $(TARGET)
	
# clean 	比目标‘clean’ 删除更多的文件,例如,
#			配置文件或为编译正常创建的准备文件,甚至makefile文件自身不能创建的文件
# 规则		找到所有.o文件进行删除
#			找到所有.d文件进行删除
#			删除show_file
distclean:
	rm -f $(shell find -name "*.o")
	rm -f $(shell find -name "*.d")
	rm -f $(TARGET)

Makefile.build文件:

PHONY := __build
__build:

obj-y :=
subdir-y :=

# 包含当前目录下的Makefile,里面含有目标文件
include Makefile

# 例子		obj-y := a.o b.o c/ d/	则subdir-y为c/ d/
# obj-y 		:= a.o b.o c/ d/
# $(filter %/, $(obj-y))   : c/ d/
#
# filter		把不符合的指定格式的文件移走
#
# $(patsubst pattern,replacement,text)
#				在‘text’中	     ----> $(filter %/, $(obj-y))
#				用‘replacement’  ----> %
#				代替匹配‘pattern’----> %/字	
# __subdir-y  	: c d
#
# subdir-y    	: c d 
__subdir-y	:= $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y	+= $(__subdir-y)

# 例子		c/built-in.o d/built-in.o
# 对于cur_ojbs变量的每一个(foreach)成员,修改成这样的$(f)/built-in.o格式
subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o)

# $(filter-out pattern...,text)
#				在‘text’中----> $(obj-y)
#				选择不匹配‘pattern’的字 -> %/
# cur_ojbs : a.o b.o
cur_ojbs := $(filter-out %/, $(obj-y))

# 对于cur_ojbs变量的每一个(foreach)成员,修改成这样的.$(f).d格式
dep_files := $(foreach f,$(cur_ojbs),.$(f).d)

# 筛选取出当前目录下已经存在的值为dep_files的文件
dep_files := $(wildcard $(dep_files))

# 如果dep_files变量不是空的话,则把生成的.$(f).d格式的文件包含进来
ifneq ($(dep_files),)
  include $(dep_files)
endif

PHONY += $(subdir-y)

__build : $(subdir-y) built-in.o

# 对于每个子目录,都执行以下规则
# 规则			执行 make -C c d -f $(TOPDIR)/Makefile.build
$(subdir-y):
	make -C $@ -f $(TOPDIR)/Makefile.build
	
# 规则(打包)	执行 arm-linux-ld -r -o built-in.o 所有得到的子目录/built-in.o 
built-in.o : $(cur_ojbs) $(subdir_objs)
	$(LD) -r -o $@ $^

# = 		用来才赋值
dep_files  = .$@.d

# 规则		执行 arm-linux-gcc -Wall -O2 -g -I -Wp,-MD,$(shell pwd)/include -c %.o %.c
%.o : %.c
	$(CC) $(CFLAGS) -Wp,-MD,$(dep_files) -c -o $@ $<
	
.PHONY : $(PHONY)

2、各子目录

2.1 display目录Makefile

# 子目录Makefile

obj-y += disp_manager.o
obj-y += fb.o

2.2 draw目录Makefile

# 子目录Makefile

obj-y += draw.o

2.3 encoding目录Makefile

# 子目录Makefile

obj-y += ascii.o
obj-y += encoding_manager.o
obj-y += utf-8.o
obj-y += utf-16be.o
obj-y += utf-16le.o

2.4 fonts目录Makefile

# 子目录Makefile

obj-y += ascii.o
obj-y += fonts_manager.o
obj-y += freetype.o
obj-y += gbk.o

猜你喜欢

转载自blog.csdn.net/weixin_42813232/article/details/107053370