天天看點

《嵌入式Linux開發實用教程》——1.2 Makefile基本知識

本節書摘來異步社群《嵌入式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中常用函數較多,筆者就不一一例舉了,讀者可參考相關書籍進行深入了解。

繼續閱讀