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

    技术2022-07-10  110

    数码相册——电子书编写通用的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 一、前言二、设计思路1、Makefile的分布2、Makefile的使用与修改2.1 顶层目录2.2 各子目录 三、编写1、顶层目录`Makefile`文件:`Makefile.build`文件: 2、各子目录2.1 `display`目录Makefile2.2 `draw`目录Makefile2.3 `encoding`目录Makefile2.4 `fonts`目录Makefile


    一、前言

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

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

    二、设计思路

    1、Makefile的分布

    分为如下3部分:

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

    2、Makefile的使用与修改

    2.1 顶层目录

    把顶层Makefile,Makefile.build放入程序的顶层目录修改顶层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
    Processed: 0.029, SQL: 9