国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
內(nèi)核頂層Makefile相關(guān)1

$(Q)變量

內(nèi)核 Makefile 文件 238 行到 259 行的注釋中知道,$(Q)變量的作用是決定是否在執(zhí)行命令時(shí)輸出詳細(xì)的命令信息。底下對其有定義: 

ifeq ($(KBUILD_VERBOSE),1)     quiet =     Q = else     quiet=quiet_     Q = @ endif

定義的意思是,如果 KBUILD_VERBOSE 為 1,則quiet 和 Q 為空,即執(zhí)行命令時(shí)會(huì)輸出命令執(zhí)行的詳細(xì)信息;否則 quiet 為 quiet_ ,Q 為 @ 。在Makefile 中,如果一個(gè)命令前使用了 @符號,那么在執(zhí)行命令時(shí)將不輸出命令的執(zhí)行詳細(xì)信息。 

拋開內(nèi)核 Makefile 文件的龐大,這里只依樣畫葫蘆的做一下實(shí)驗(yàn),下面是一個(gè)測試 Makefile :

KBUILD_VERBOSE := 1 ifeq ($(KBUILD_VERBOSE), 1)     quiet =     Q = else     quite = quiet_     Q = @ endif all:     $(Q)mkdir -p /home/beyes/makefile_test/quite/test_quite

Make一下: 

beyes@debian:~/makefile_test/quite$ make mkdir -p /home/beyes/makefile_test/quite/test_quite

由執(zhí)行結(jié)果看到,Makefile 中的 mkdir命令執(zhí)行過程整個(gè)輸了出來。 

再改一下 Makefile 中的 KBUILD_VERBOSE := 1 為KBUILD_VERBOSE := 0,那么再次執(zhí)行make 時(shí),已經(jīng)看不見任何輸出。

= 和 :=符號的區(qū)別

= 和 := 都是變量賦值符號。但是它們有些區(qū)別:

"=" 如果右值包含另一個(gè)變量,那么可以在后面定義這個(gè)變量。":=" 如果右值包含另一個(gè)變量,則只能引用已定義的變量。

下面看示例:

drivers-y := drivers/ $(head-y)head-y = header/all:    @echo $(drivers-y)

輸出:

$ make    drivers/

drivers-y 的后面跟著一個(gè) $(head-y)變量,這個(gè)變量在 drivers-y 之前并未定義過,但是由于這里使用了 := 符號,所以在 drivers-y 的下一行再定義head-y 已然無效。

那么將上面的 drivers-y 中的符號改成 = 符號,那么便可以看到區(qū)別:

drivers-y = drivers/ $(head-y)head-y = header/all:    @echo $(drivers-y)

輸出:

[beyes@SLinux Makefile]$ make    drivers/ header/

=

 = 符號的用法如:

var = def

這里的意思是,如果 var這個(gè)變量沒有被定義過,那么它的值就被定義為 def 。如果被定義過,則 def 不會(huì)被賦值到 var 中:

var = defall:    @echo $(var)

輸出:

$ make    def

如果是:

var = definedvar = defall:    @echo $(var)

則輸出:

$ make    defined

+/-符號

 make 通常會(huì)在命令運(yùn)行結(jié)束后檢查命令的執(zhí)行的返回狀態(tài),如果返回成功,那么就啟動(dòng)一個(gè)子shell 來執(zhí)行下一條命令;如果在中途檢測到有執(zhí)行出錯(cuò)的情況(返回非 0狀態(tài)),那么就會(huì)放棄對當(dāng)前規(guī)則后續(xù)命令的執(zhí)行,甚至?xí)K止所有規(guī)則的執(zhí)行。但在某些情況下,規(guī)則中一個(gè)命令執(zhí)行失敗并不代表整個(gè)規(guī)則執(zhí)行錯(cuò)誤,所以完全可以忽略這條可能執(zhí)行失敗的命令,其忽略的方法是在命令前添加一個(gè) '-' 符號。在 Makefile 經(jīng)??吹皆?include面前添加 '-' 符號:-include ,這時(shí)當(dāng)當(dāng) include 包含的文件不存在時(shí)也不會(huì)造成整個(gè) Makefile解析的終止。又如,當(dāng)一條 rm 命令前添加 ‘-’ 符號時(shí),如果要?jiǎng)h除的文件不存在或刪除文件失敗也不會(huì)對整個(gè)流程有任何影響。

除了 '-' 符號外,還可以看到 '+' 符號,它的意思和 '-' 相反,表示不忽略。這就意味著,像 make 的命令行選項(xiàng)-n(--just print), -t(touch) 并不影響之前帶 '+' 符號的命令的執(zhí)行。像 -n選項(xiàng),一般情況下,它只是在解析命令,而不真正執(zhí)行它們,但是命令前使用了 '+' 之后, -n選項(xiàng)就不能阻止命令被執(zhí)行。如一個(gè)目錄下有這幾個(gè)文件:

$ ls    Makefile test2.txt test.txt

Makefile 的內(nèi)容為:

all:    @rm -f test.txt    +@rm -f test2.txt

使用 -n 選項(xiàng)來運(yùn)行 make:

$ make -n    rm -f test.txt    rm -f test2.txt

再檢查一下當(dāng)前目錄:

$ ls    Makefile test.txt

可見 test2.txt已經(jīng)被刪除。 

@:

在一些 Makefile 中可能會(huì)在偽目標(biāo)下的命令中看到 @: 這個(gè)符號,其實(shí)這不是代表一個(gè)特殊變量。這里的 @ 符號和@echo 中表示的意思(不顯示命令執(zhí)行的詳細(xì)內(nèi)容)一樣,而冒號 ":" 實(shí)際上是 shell 中的內(nèi)置符號,它表示的是一種空命令,什么都不做,也就是執(zhí)行到它時(shí),它上面的命令都已經(jīng)成功執(zhí)行,最后成功退出。

$$

在使用變量時(shí),需要在變量前加 "$" 符號,但最好是用 () 或 {} 將變量括起來,比如 $(VAR) 或 ${VAR}。如果要使用真實(shí)的 "$“ 字符,那么需要用兩個(gè) "$" 表示,即 "$$"。

比如下面的代碼:

$ cat Makefileall:    @echo "$$HOME"    @echo "$$BASH"    @echo "$$PATH"

運(yùn)行輸出:

$ make    /home/beyes    /bin/sh    /usr/local/Trolltech/Qt-4.3.2/bin:/usr/lib/qt-3.3/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/beyes/bin

上面,$HOME,$BASH,$PATH都是系統(tǒng)內(nèi)置變量。引用這些變量時(shí),就需要用 $$,如果只用一個(gè) $ (如 @echo"$HOME"),那么你不會(huì)看到你所希望看到的結(jié)果。

$^,$+,$*,$(@D),$(@F),$(*D),$(*F),$(%D),$(%F),

$(%D),$(%F),$(

$(?D),$(?F)

$^、$+:
$^ 表示所有依賴文件列表。一個(gè)文件可重復(fù)出現(xiàn)在目標(biāo)的依賴中,$^ 只記錄它的一次引用情況,也就是說 $^ 會(huì)去掉重復(fù)的依賴文件。$+類似于 $^,但它保留了依賴文件中重復(fù)出現(xiàn)的文件。下面舉例說明這兩個(gè)變量的區(qū)別。

先在一個(gè)目錄下建立 3 個(gè)文件:

$ echo "are" > test1.txt$ echo "you" > test2.txt$ echo "ok" > test3.txt

測試代碼:

all:test1.txt test2.txt test3.txt test1.txt    $(shell cat $^ > integra1)    $(shell cat $+ > integra2)

運(yùn)行輸出:

beyes@debian:~/Makefile/prereq$ cat integra1    are    you    okbeyes@debian:~/Makefile/prereq$ cat integra2    are    you    ok    are

由輸出可以很清楚的看到這兩個(gè)變量的區(qū)別。

$*
$* 有一個(gè)形象的詞來稱呼它 --- “莖” 。如果目標(biāo)文件名中帶有一個(gè)可識別的后綴,那么 $* 就表示文件中移除后綴以外的部分。比如main.o 作為目標(biāo)時(shí),$* 就表示為 main 。如果目標(biāo)包含不可識別的后綴時(shí),該變量為空。

$(@D)
代表目標(biāo)文件的目錄部分(要去掉目錄部分的最后一個(gè)斜杠),如下例所示:

/home/beyes/Makefile/main.o:    @echo $(@D)

運(yùn)行輸出:

$ make    /home/beyes/Makefile

如果目標(biāo)中不包含斜杠,那么輸出值為 '.'表示當(dāng)前目錄。

$(@F)
目標(biāo)文件的完整文件名初目錄以外的部分,換句話說表示的是實(shí)際的文件名。如下示例:

/home/beyes/Makefile/main.o:    @echo $(@F)

運(yùn)行輸出:

$ make    main.o

$(*D) 和 $(*F)

分別表示目標(biāo) “莖” 中的目錄部分和文件名部分。如下示例:

/home/beyes/Makefile/main.o:    @echo $(*D)    @echo $(*F)

運(yùn)行輸出:

$ make    /home/beyes/Makefile    main

$(%D) 和 $(%F)

當(dāng)以 "archive(member)" 這樣形式的靜態(tài)庫為目標(biāo)時(shí),分別表示庫文件成員 "member"名中的目錄部分和文件名部分。它僅對這種形式的規(guī)則目標(biāo)有效。如下示例:

Mylib.a(/home/beyes/main/are.o):    @echo $(%D)    @echo $(%F)

運(yùn)行輸出:

$ make    /home/beyes/main    are.o

$(

分別表示規(guī)則中第一個(gè)依賴文件的目錄部分和文件名部分。如下示例:

/home/beyes/main/are.o:    @echo hellosomething.o:    @echo makefileall:/home/beyes/main/are.o something.o    @echo $(<<span style="color: #000000;">D)    @echo $(

運(yùn)行輸出:

$ make all    hello    makefile    /home/beyes/main    are.o

$(^D) 和 $(^F)

分別表示所有依賴文件的目錄部分和文件部分(不存在同一文件)。如下示例:

/home/beyes/main/are.o:    @echo hello/home/beyes/something.o:    @echo makefileall:/home/beyes/main/are.o /home/beyes/something.o    @echo $(^D)    @echo $(^F)

運(yùn)行輸出:

$ make all    hello    makefile    /home/beyes/main /home/beyes    are.o something.o

$(+D) 和 $(+F)

分別表示所有依賴文件的目錄部分和文件部分(可存在重復(fù)文件)。

$(?D) 和$(?F)
分別表示被更新的依賴文件的目錄部分和問及文件部分。

error函數(shù)

error 函數(shù)表示產(chǎn)生了一個(gè)致命錯(cuò)誤,當(dāng)它執(zhí)行后,編譯會(huì)停止。
它的使用方法是:

$(error <錯(cuò)誤消息>)

測試代碼:

KBUILD_VERBOSE := 1 TEST_MSG := "are you ok?" ifeq ($(KBUILD_VERBOSE), 1)     $(error KBUILD_VERBOSE is $(KBUILD_VERBOSE), we will stop here)     quite =     Q = else     quite = quiet_     Q = @ endif all:     $(Q)echo $(TEST_MSG)

運(yùn)行輸出: 

beyes@debian:~/makefile_test/error$ makeMakefile:7: *** KBUILD_VERBOSE is 1, we will stop here。 停止。

由輸出可見,all: 目標(biāo)下的 echo語句并沒有執(zhí)行輸出,整個(gè)編譯在 error 函數(shù)執(zhí)行后停止了。如果將上面的 KBUILD_VERBOSE 的值改為 0 ,那么再make 時(shí)輸出: 

beyes@debian:~/makefile_test/error$ makeare you ok?

$@, $^, $< , $?符號

Makefile $@, $^, $<</p>

$@ 表示目標(biāo)文件$^ 表示所有的依賴文件$<<span style="color: #000000;"> 表示第一個(gè)依賴文件$? 表示比目標(biāo)還要新的依賴文件列表

如一個(gè)目錄下有如下文件:

$ lshello.c hi.c main.c Makefile

按照 Makefile 規(guī)則規(guī)規(guī)矩矩的寫:

main: main.o hello.o hi.o    gcc -o main main.o hello.o hi.omain.o: main.c    cc -c main.chello.o: hello.c    cc -c hello.chi.o: hi.c    cc -c hi.cclean:    rm *.o    rm main

改為用上述符號進(jìn)行替代:

main: main.o hello.o hi.o    gcc -o $@ $^main.o: main.c    cc -c $<<span style="color: #000000;">hello.o: hello.c    cc -c $<<span style="color: #000000;">hi.o: hi.c    cc -c $<<span style="color: #000000;">clean:    rm *.o    rm main
beyes@debian:~/makefile_test/semicolon/real$ make    cc -c main.c    cc -c hello.c    cc -c hi.c    gcc -o main main.o hello.o hi.obeyes@debian:~/makefile_test/semicolon/real$ ls    hello.c hello.o hi.c hi.o main main.c main.o Makefile

patsubst 和 filter函數(shù)

filter 函數(shù)的使用形式如:

$(filter , )

該函數(shù)的功能是,以 模式過濾 字符串中的單詞,保留符合模式的單詞。

該函數(shù)的返回值是符合 模式的字符串。

patsubst 函數(shù)的使用形式如:

$(patsubst , , )

該函數(shù)的功能是,查找中的單詞(這些單詞以“空格”、“Tab”或“回車”,“換行”分隔)是否符合 中的模式,如果匹配,那么使用 替換。這里, 可以包括通配符“%” (表示任意長字符串)。如果 中也包含 “%” 符號,那么 中的 “%” 所代表的字符串就是 中的的那個(gè)字符串。若要使用 %字符,那么要使用 ‘\’ 符號進(jìn)行轉(zhuǎn)義,即 “\%” 。

函數(shù)的返回值是替換過的字符串。


下面使用一個(gè)實(shí)例說明這兩個(gè)函數(shù)的應(yīng)用。下面的代碼摘自內(nèi)核源碼樹下頂層的 Makefile, 為了演示,做了一點(diǎn)修改:

init-y := init/ testdrivers-y := drivers/ sound/net-y := net/ test2libs-y := lib/core-y := usr/vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y)                        $(core-y) $(drivers-y)                        $(net-y) $(libs-y) ))vmlinux-dirs2 := $(init-y) $(drivers-y) $(net-y) $(libs-y) $(core-y)all:    @echo vmlinux-dirs2: $(vmlinux-dirs2)    @echo vmlinux-dirs: $(vmlinux-dirs)            

運(yùn)行輸出:

linux-suse10:~/Makefile_test # make    vmlinux-dirs2: init/ test drivers/ sound/ net/ test2 lib/ usr/    vmlinux-dirs: init usr drivers sound net lib

由上面的vmlinux-dirs2輸出可見,所有變量內(nèi)容都被輸出。

對vmlinux-dirs 的輸出,則體現(xiàn)了上述兩個(gè)函數(shù)的應(yīng)用。首先 filter 過濾掉了沒有以 /符號作為結(jié)尾的字符串;然后再經(jīng)過 patsubst 函數(shù)過濾掉了所有以 / 符號結(jié)尾字符串中的 / 符號。

filter-out --反過濾函數(shù)

格式:

$(filter-out ,)

說明:

以 模式過濾 字符串中的單詞,去除符合模式 的單詞。返回不符合模式 的字符串。如果 是一樣或者是其子集,那么返回空。
如:

objs = hello.c world.c are.c you.c ok.cnew = hello.c world.c are.c you.c ok.c add.call:    @echo $(filter-out $(new), $(objs))

運(yùn)行輸出時(shí)為空。當(dāng) new 改為和 objs一樣時(shí),同樣輸出為空。當(dāng) new 改為hello.c world.c are.c you.c 時(shí),輸出 ok.c。

再做一個(gè)實(shí)驗(yàn),如果 new 中包含的字符串比 objs 中的還是少一個(gè) ok.c ,但是字符串的順序和 ojbs中的不一樣,那結(jié)果是不是仍然輸出 ok.c 呢?答案是一定的!這一無關(guān)順序的“智能”特性比較重要,像在內(nèi)核 Makefile的參數(shù)檢查中(比較新舊編譯選項(xiàng)是否一樣)就體現(xiàn)了這一點(diǎn),如在 script/Kbuild.include 中對arg-check的定義體現(xiàn)了這一點(diǎn):

arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@))                     $(filter-out $(cmd_$@), $(cmd_$(1))) )

origin 函數(shù) --告知變量的出生情況

origin 函數(shù)的作用是告訴你變量是哪里來的,其出生狀況如何,他并不改變變量。其語法是:

$(origin )

上面, 為變量的名字,而不是引用,所以一般沒有 $字符在前。origin 函數(shù)通過返回值來告訴你 的出生情況。下面用實(shí)例說明:

1. 當(dāng)從來未定義過該變量時(shí),origin 函數(shù)返回 "undefined" 。如下面的 Makefile 代碼:

all:    @echo $(origin V)

運(yùn)行輸出:

$ make    undefined

2. 如果該變量為環(huán)境變量,那么返回 "enviroment"。如下面的 Makefile 代碼:

all:    @echo $(origin USER)

運(yùn)行輸出:

$ make    environment

其中 USER 這個(gè)變量為系統(tǒng)定義的當(dāng)前用戶,使用 env命令可以看到。

3. 如果變量是個(gè)默認(rèn)定義,那么返回 "default"。如下面的 Makefile 代碼:

all:    @echo $(origin CC)

運(yùn)行輸出:

$ make    default

4. 如果一個(gè)變量被定義在 Makefile 文件中,那么返回"file" 。如下面的 Makefile 代碼:

V := 1all:    @echo $(origin V)

運(yùn)行輸出:

$ make    file

5. 如果變量來自命令行,那么返回 "command line"。如下面的 Makefile 代碼:

all:    @echo $(origin MyVar)

運(yùn)行方法:

$ make MyVar="Are you ok?"    command line

6. 如果變量被 override 被重新定義過,那么返回"override"。如下面的 Makefile 代碼:

verride SHELL = /bin/shall:    @echo $(origin SHELL)

運(yùn)行輸出:

$ make    override

上面,SHELL 原本是個(gè)環(huán)境變量,但在 Makefile 里被override 指示符重定義過。

7. 如果變量是自動(dòng)化變量(如 $@, $< 等),那么返回 "automatic" 。如下面的 Makefile代碼:

all:    @echo $(origin @)

運(yùn)行輸出:

$ make    automatic

ifdef, ifndef, ifeq,ifneq, endif

用內(nèi)核 Makefile 中的一段代碼說明: 

# To put more focus on warnings, be less verbose as default# Use 'make V=1' to see the full commandsifdef V    ifeq ("$(origin V)", "command line")            KBUILD_VERBOSE = $(V)    endifendififndef KBUILD_VERBOSE      KBUILD_VERBOSE =0endif

代碼中注釋的意思是,為了能將精力集中在警告信息上面,默認(rèn)上不輸出詳細(xì)而顯得冗余的編譯信息,如果想看到完整的命令執(zhí)行情況,可以在make 時(shí)使用參數(shù) V=1 。 

下面根據(jù)代碼分析這 4 個(gè)符號的作用,實(shí)際上它們和 C 語言中的意思是一樣的。 
ifdef V 表示如果 V 變量被定義過,那么會(huì)執(zhí)行下面的 ifeq 語句。V變量的定義來源可以有不同,如在文件中定義,在命令行中定義,在環(huán)境變量中定義等。 
ifeq ("$(origin V)", "command line") 表示若 V 是在命令行里已被定義,那么執(zhí)行下面的KBUILD_VERBOSE = $(V) 語句。也就是說,ifeq用以判斷后面括號里的兩個(gè)值是否相等,如果相等則執(zhí)行下面的語句。如果不相等,則不執(zhí)行。
ifndef 表示如果后面的變量沒有被定義過,則執(zhí)行其下面的語句。 
上面,每個(gè) ifdef , ifeq 和 ifndef 都要和一個(gè) endif 匹配以構(gòu)成一個(gè)完整的判斷式。

 
另外,在內(nèi)核 Makefile 中還有如對 (C) 以及 (M) 等選項(xiàng)同樣分析。
(C) 選項(xiàng)有是關(guān)于代碼檢查的選擇:

# Call a source code checker (by default, "sparse") as part of the# C compilation.## Use 'make C=1' to enable checking of only re-compiled files.# Use 'make C=2' to enable checking of *all* source files, regardless# of whether they are re-compiled or not.## See the file "Documentation/sparse.txt" for more details, including# where to get the "sparse" utility.ifdef C    ifeq ("$(origin C)", "command line")         KBUILD_CHECKSRC = $(C)    endifendififndef KBUILD_CHECKSRC    KBUILD_CHECKSRC =0endif

(M) 選項(xiàng)關(guān)于模塊的編譯:

# Use make M=dir to specify directory of external module to build# Old syntax make ... SUBDIRS=$PWD is still supported# Setting the environment variable KBUILD_EXTMOD take precedenceifdef SUBDIRS    KBUILD_EXTMOD ?= $(SUBDIRS)endififdef M    ifeq ("$(origin M)", "command line")        KBUILD_EXTMOD := $(M)    endifendif    

像我們經(jīng)常編譯驅(qū)動(dòng)模塊時(shí)會(huì)使用下面的命令:make -C/lib/modules/`uname -r`/build M=`pwd` modules

上面,使用 pwd 命令給出了要編譯的模塊所在的路徑。

像 ifeq 和 ifneq的第一個(gè)參數(shù)也可以不止一個(gè)變量,當(dāng)有多個(gè)變量時(shí),可能需要考慮每個(gè)變量的條件是否都滿足判斷條件,直到所有的變量都不滿足時(shí),才認(rèn)為整個(gè)表達(dá)式是不滿足的。示例代碼如下:

hostprogs-y := 1hostprogs-m :=ifneq ($(hostprogs-y)$(hostprogs-m),)    testvar := "defined"endifall:    @echo "$(testvar)"

運(yùn)行輸出:

$ make    defined

如果將上面代碼中對 hostprogs-y的定義設(shè)為空,那么輸出將為空;而 hostprogs-y 和 hostprogs-m 這兩個(gè)變量只要有一個(gè)味真,那么就認(rèn)為整個(gè)ifneq 判斷成立。

網(wǎng)址:http://www.cnblogs.com/baiyw/p/3303758.html

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
$(if $(KBUILD_VERBOSE:1=),@) 語法釋疑
Makefile中的$@, $^, $< , $?, $%, $+, $*
如何控制Kbuild的行為
Linux內(nèi)核構(gòu)建系統(tǒng)之六
Linux下Makefile文件的的規(guī)則格式與變量
gcc Makefile 入門
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服