本節書摘來異步社群《嵌入式linux開發實用教程》一書中的第1章,第1.2節,作者:朱兆祺 ,李強 ,袁晉蓉 ,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視
嵌入式linux開發實用教程
makefile如今能得以廣泛應用,這還得歸功于它被包含在unix系統中。在make誕生之前,unix系統的編譯系統主要由“make”、“install”shell腳本程式和程式的源代碼組成。它可以把不同目标的指令組成一個檔案,而且可以抽象化依賴關系的檢查和存檔。這是向現代編譯環境發展的重要一步。1977年,斯圖亞特·費爾德曼在貝爾實驗室裡制作了這個軟體。2003年,斯圖亞特·費爾德曼因發明了這樣一個重要的工具而接受了美國計算機協會(acm)頒發的軟體系統獎。
makefile檔案可以實作自動化編譯,隻需要一個“make”指令,整個工程就能完全自動編譯,極大地提高了軟體開發的效率。目前雖有衆多依賴關系檢查工具,但是make是應用最廣泛的一個。一個程式員會不會寫makefile,從一個側面說明了這個程式員是否具備完成大型工程的能力。
一個簡單的makefile語句由目标、依賴條件、指令組成。
obj := $(objtree)/
objtree := $(if $(build_dir),$(build_dir),$(curdir))
export build_dir=/tmp/build<code>`</code>
$(if $(build_dir),$(build_dir),$(curdir))的含義:如果“build_dir”變量值不為空,則将變量“build_dir”指定的目錄作為一個子目錄;否則将目錄“curdir”作為一個子目錄。
2.遞歸展開式變量
這類變量的定義是通過“=”和“define”來定義的。
x = $(y)
y = $(z)
z = $(x)<code>`</code>
這樣的話會使得makefile出錯,因為到最終引用了自己。
其二,這種風格的變量定義中如果使用了函數,那麼包含在變量值中的函數總會在變量被引用的地方執行。
3.直接展開式變量
為了避免遞歸展開式變量存在的問題和不友善,gnu make支援另外一種風格的變量,稱為直接展開式變量。這種風格的變量使用“:=”定義。在使用“:=”定義變量時,變量值中對其他變量或者函數的引用在定義變量時被展開,也就是對變量進行替換。
x := student
x ?= teacher
all:
@echo $(x)<code>`</code>
由于x在之前被指派了,是以這裡的輸出是student。
5.變量的替換引用
對于一個已經定義的變量,可以使用變量的替換引用将變量中的字尾字元使用指定的字元替換。格式為“$(x:a=b)”(或者“${x:a=b}”),即将變量“x”中所有以“a”字元結尾的字替換為以“b”結尾的字。
x = fun.o main.o
x += sub.o
這裡的輸出是:fun.o main.o sub.o。
1.ifneq關鍵字
這個關鍵字是用來判斷兩個參數是否不相等。格式為:
version = 2013
patchlevel = 04
sublevel =
extraversion =
ifneq "$(sublevel)" ""
u_boot_version = $(version).$(patchlevel).$(sublevel)$(extraversion)
else
u_boot_version = $(version).$(patchlevel)$(extraversion)
endif<code>`</code>
先将sublevel使用$()展開和替換,如果sublevel的值不是空,則執行:
ifeq “value1”“value2”
ifeq (value1,value2)<code>`</code>
和ifneq一樣,先要将value1和value2展開替換之後,再進行比較。
ifndef value<code>`</code>
由于在makefile中,沒有定義的變量的值為空。
subdirs += $(subdir_examples)<code>`</code>
否則不執行。
4.ifdef關鍵字
ifdef關鍵字用來判斷一個變量是否已經進行定義過。格式:
ifdef config_sys_ldscript
# need to strip off double quotes
ldscript := $(subst ",,$(config_sys_ldscript))
如果config_sys_ldscript定義過,則執行:
zhu := $(shell cat func)
all:
@ echo $(zhu)<code>`</code>
func檔案中的内容:
zhuzhaoqi@zhuzhaoqi-desktop:~/u-boot/makefile/shellfunction$ make
juxst zhuzhaoqi<code>`</code>
在u-boot和linux核心源碼中将會大量使用到shell函數。
3.subst函數
subst函數是字元串替換函數,文法為:
$(subst 被替換字串 替換字串 替換操作字元串)
執行subst函數之後,傳回的是執行替換操作之後的字元串。如下:
echo zhu zhaoqi
zhu zhaoqi<code>`</code>
即将“z”替換成了“z”。
4.dir函數
dir函數作用為取出該檔案的目錄,其文法為:
$(dir 檔案名稱)
執行該函數之後傳回檔案目錄部分。
makefile中常用函數較多,筆者就不一一例舉了,讀者可參考相關書籍進行深入了解。