音影先锋亚洲天堂网|电影世界尽头的爱完整版播放|国产 熟女 91|高清无码免费观看欧美日韩|韩国一区二区三区黄色录像|美女亚洲加勒比在线|亚洲综合网 开心五月|7x成人在线入口|成人网站免费日韩毛片区|国产黄片?一级?二级?三级

登錄 免費(fèi)注冊 首頁 | 行業(yè)黑名單 | 幫助
維庫電子市場網(wǎng)
技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng)
驅(qū)動編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機(jī) | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計(jì) | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe

Makefile使用初步

作者:shenlan51 欄目:嵌入式系統(tǒng)
Makefile使用初步
   
  原文見這里:
http://www.mcublog.com/more.asp?NAME=shenlan&id=10854

  一. 為什么使用變量
  變量在makefile中用來代表一個(gè)字符串,用來表示




1. 一系列文件的名字
2. 傳遞給編譯器的參數(shù)
3. 需要運(yùn)行的程序
4. 需要查找源代碼的目錄
5. 你需要輸出信息的目錄
6. 你想做的其它事情。





說白了,這有些類似于編程語言中的宏。

   二. 定義變量的方式和建議
   變量的名字是大小新敏感的,從大的方面來說,makefile中的變量被分為兩種,一個(gè)是用=來定義的,老外叫right-hand sides of variable,另外一種是用define關(guān)鍵字定義的,叫做bodies of variable。先簡單說這些,后面詳述。
   傳統(tǒng)上使用大寫字母為變量命名,但是GNU推薦使用小寫字母作為makefile內(nèi)部使用的變量的名字,并用大寫字母定義隱式規(guī)則中的參數(shù)或在命令行中允許用戶重新定義的參數(shù)。

   三. 基本的變量引用
   用$(NAME)或${NAME}來引用一個(gè)變量,所以當(dāng)你要表示一個(gè)$符號時(shí),你要使用$$。當(dāng)你只使用一個(gè)字母作為變量的名字時(shí),你可以用$NAME來引用這個(gè)變量,不過GNU 并不推薦這樣做,因?yàn)檫@種方式通常用來引用自動變量(Automatic Variables)。

    四. 兩種風(fēng)格的變量定義

GNU有兩種定義變量的方式,它們的不同體現(xiàn)在定義它們的風(fēng)格和他們被展開的方式。
   第一類叫做遞歸展開變量(Recursively Expanded Variable)。用=或define關(guān)鍵字都
可以定義這種變量,如果變量的定義引用了其它的變量,那么引用會一直展開下去,
直到找到被引用的變量的最新的定義,并以此作為改變量的值返回。例如:





代碼:

foo = $(bar)
bar = $(ugh)
ugh = Huh?







$(foo)的值究竟是什么呢? $(foo)被展開成$(bar),$(bar)被展開成$(ugh),最終$(ugh)
被展開成“Huh?”,那么$(foo)的值就是“Huh?”這種類型的變量是所有其他make工具支持
的變量類型。它有著自己的有點(diǎn)和缺點(diǎn):
優(yōu)點(diǎn):
它可以向后引用變量
缺點(diǎn):
1).你不能對該變量進(jìn)行任何擴(kuò)展,例如
CFLAGS=$(CFLAGS) -O
會造成無限循環(huán)展開,所有對于遞歸展開變量,這樣做是不允許的。
2).如果makefile中的某個(gè)變量調(diào)用了某些函數(shù),那么在變量被展開的每一次,函數(shù)都會被調(diào)用,
說的好些,無非是make慢點(diǎn),更壞的情況是一些 shell函數(shù)和通配符的重復(fù)調(diào)用的結(jié)果往往
是難以預(yù)知的。
最后,用一個(gè)例子說明上面的問題。用這個(gè)makefile試一下就明白了(分別開啟和注銷掉第三行,
你就能看到結(jié)果)





代碼:

bar = TEST
foo = $(bar)
bar = $(ugh)
ugh = Huh?
all: ;echo foo








為了解決這些問題,GNU定義了另一中其它風(fēng)格的變量,叫做簡單擴(kuò)展變量(Simply Expanded Variables)
簡單擴(kuò)展變量用符號:=來定義,用這種方式定義的變量,會在變量的定義點(diǎn),按照被引用的變量的當(dāng)前值
進(jìn)行展開。同樣寫個(gè)例子,測試一下,這東西用文字表達(dá)太困難了





代碼:

m := mm
x := $(m)
y := $(x) bar
x := later
all:;echo $(x) $(y)







這種定義變量的方式更適合在大的編程項(xiàng)目中使用,因?yàn)樗裎覀円话愕木幊陶Z言。

其實(shí),GNU還對makefile中定義變量的方式進(jìn)行了第三種擴(kuò)展,用?=定義變量,它的含義是如果變量還沒定義
就定義它,例如 FOO ?= Am I defined?,那么,它相當(dāng)于下面的代碼片斷





代碼:

ifeq ($(origin FOO), undefined)
   FOO = Am I defined?
endif







這種寫法可以用于為用戶提供默認(rèn)的選項(xiàng),即如果用戶不定義,就提供給他默認(rèn)的。另外,要說明的是把變量
定義成NULl,也是定義了變量,此時(shí)?=將不再起作用。

注意:
最后要說的是,無論我們使用那種風(fēng)格定義變量,都不要在定義變量的行后面加上隨機(jī)數(shù)目的空格,之后寫注釋,
這個(gè)我們想象的是不一樣的,例如
ml = MAGIC_linux

ml = MAGIC_linux # My favourite linux distribution
這是兩個(gè)完全不同的變量,其中第一個(gè)ml的值是MAGIC_linux,而后一個(gè)的值是‘MAGIC_linux ’,所以除非
你有意要定義末尾帶有空格的變量,否則不要在定義變量行末尾隨便添加空格和注釋。

五. 高級的變量引用方法
有兩種方法: 1. 替換變量引用 2. 計(jì)算變量的值(更確切的說是推導(dǎo))

第一種
定義方法: $(var: a=b) ${var: a=b}
意義:把其變量a的值中,每一個(gè)詞的最后一個(gè)字幕換成b
例如:





代碼:

foo := a.o b.o c.o
bar := $(foo:.o=.c)
all:;echo $(bar)







這時(shí),bar的值等于a.c b.c c.c
另外,我們還可以用bar := $(foo:%.o=%.c)的形式

第二種
這是一種高級的makefile編程技術(shù),一般我們很少使用它,但是它并不難,先看個(gè)例子





代碼:

x = y
y = z
a := $($(x))







此時(shí),a的值是什么呢?答案是z。因?yàn)閮?nèi)層的$(x)=y,而外層的$(y)=z,也就是說a的值是通過$(x)計(jì)算出來的,所以
叫做計(jì)算變量的值。當(dāng)然嵌套可是有很多層,自己試試吧,不多說了。在嵌套變量引用的時(shí)候,還可以包含函數(shù)調(diào)用,
例如:





代碼:

x = variable1
variable2 := Hello
y = $(subst 1,2,$(x))
z = y
a := $($($(z)))







一番推導(dǎo),a的值等于Hello
整個(gè)變量的推導(dǎo)過程中可以涉及到多個(gè)變量,這樣,一個(gè)變量就可以有多個(gè)字面值,例如:





代碼:

a_dirs := dira dirb
1_dirs := dir1 dir2

a_files := filea fileb
1_files := file1 file2

ifeq "$(use_a)" "yes"
a1 := a
else
a1 := 1
endif

ifeq "$(use_dirs)" "yes"
df := dirs
else
df := files
endif

dirs := $($(a1)_$(df))







根據(jù)usa_a和use_dirs這兩個(gè)兩個(gè)變量的值,dirs可以有不同的值

另外,推導(dǎo)變量值還可以用在替換變量引用中,例如:





代碼:

a_objects := a.o b.o c.o
1_objects := 1.o 2.o 3.o

sources := $($(a1)_objects:.o=.c)







根據(jù)上面a1值的不同,source可以等于a.c b.c c.c或1.c 2.c 3.c

這種內(nèi)嵌變量的限制是你不能把函數(shù)調(diào)用作為定義變量的一種方式,舉個(gè)例子





代碼:

ifdef do_sort
func := sort
else
func := strip
endif

bar := a d b g q c

foo := $($(func) $(bar))







foo的是什么呢?它是sort a d b g q c或strip a d b g q c,而并不是我們想象的把a(bǔ) d b g q c作為參數(shù)
傳遞給sort或strip

你還可以把推導(dǎo)出來的變量名作為變量的左值





代碼:

dir = foo
$(dir)_sources := $(wildcard $(dir)/*.c)








最后要說明的是,要注意把遞歸擴(kuò)展變量和嵌套推廣變量區(qū)分開。

六. 變量得到值的辦法





1) 在你運(yùn)行make的時(shí)候覆蓋變量的值,例如make CFLAGS='-g -O'
2) 在makefile中用上面說的方式為變量賦值
3) 設(shè)定的環(huán)境變量可以在makefile中成為變量
4) GNU定義的一些自動變量,詳見http://www.gnu.org/software/make/manual/html_chapter/make_10.html#SEC111
5) 一些變量有固定的初始值,詳見http://www.gnu.org/software/make/manual/html_chapter/make_10.html#SEC106

七. 為變量添加值
你可以通過+=為已定義的變量添加新的值,例如





代碼:

objects = main.o foo.o bar.o utils.o
objects += another.o







看上去,+=有些和下面的代碼類似





代碼:

objects = main.o foo.o bar.o utils.o
objects := $(objects) another.o







但是,它們還是存在這一些不同

當(dāng)變量從前沒有被定義過, +=和=是一樣的,它定義一個(gè)遞歸展開的變量,但是,當(dāng)變量已經(jīng)有定義的時(shí)候,+=只是簡單
的進(jìn)行字符的添加工作。

如果起初你用:=定義變量,那么+=只是利用變量的當(dāng)前值進(jìn)行添加,這和我們的直覺是一樣的,例如:
variable := MAGIC_
variable += linux
此時(shí)variable的值就是MAGIC_linux

如果起初用=定義變量,+=的行為就變得有些古怪,它并不會在使用+=的地方馬上進(jìn)行變量展開,而是會把展開工作推后,
直到它找到最后變量的定義,這和=定義變量的行為是類似的,但是總覺得不合直覺,例如:





代碼:

var = I love
variable = linux

var += $(variable)

variable = MAGIC

all:;echo $(var)







當(dāng)你使用var := I love和上面的情
參與討論
昵稱:
討論內(nèi)容:
 
 
相關(guān)帖子
請問哪里有I-Logix Rhapsody 軟件? 謝謝!
誰有USB2.0修訂版的協(xié)議規(guī)范
求助:哪里有ARM-LINUX及其編譯調(diào)試工具下載?
求能用到philips的lpc2214上的jtag電路圖???
原來是加2頭文件順序也這么重要
免費(fèi)注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點(diǎn)此進(jìn)入


Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號