第三階段應用層——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工具鏈


一、前言

對於之前的電子書,需要設計一個比較通用的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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章