<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    DANCE WITH JAVA

    開發出高質量的系統

    常用鏈接

    統計

    積分與排名

    好友之家

    最新評論

    (轉)跟我一起寫 Makefile(十)

    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2895

    四、 foreach 函數

    ?

    foreach 函數和別的函數非常的不一樣。因為這個函數是用來做循環用的, Makefile 中的 foreach 函數幾乎是仿照于 Unix 標準 Shell /bin/sh )中的 for 語句,或是 C-Shell /bin/csh )中的 foreach 語句而構建的。它的語法是:

    ?

    ??? $(foreach <var>,<list>,<text>)

    ?

    這個函數的意思是,把參數 <list> 中的單詞逐一取出放到參數 <var> 所指定的變量中,然后再執行 <text> 所包含的表達式。每一次 <text> 會返回一個字符串,循環過程中, <text> 的所返回的每個字符串會以空格分隔,最后當整個循環結束時, <text> 所返回的每個字符串所組成的整個字符串(以空格分隔)將會是 foreach 函數的返回值。

    ?

    所以, <var> 最好是一個變量名, <list> 可以是一個表達式,而 <text> 中一般會使用 <var> 這個參數來依次枚舉 <list> 中的單詞。舉個例子:

    ?

    ??? names := a b c d

    ??? files := $(foreach n,$(names),$(n).o)

    ?

    上面的例子中, $(name) 中的單詞會被挨個取出,并存到變量“ n ”中,“ $(n).o ”每次根據“ $(n) ”計算出一個值,這些值以空格分隔,最后作為 foreach 函數的返回,所以, $(files) 的值是“ a.o b.o c.o d.o ”。

    ?

    注意, foreach 中的 <var> 參數是一個臨時的局部變量, foreach 函數執行完后,參數 <var> 的變量將不在作用,其作用域只在 foreach 函數當中。

    ?

    ?

    五、 if 函數

    ?

    if 函數很像 GNU make 所支持的條件語句—— ifeq (參見前面所述的章節), if 函數的語法是:

    ?

    ??? $(if <condition>,<then-part>)

    ?

    或是

    ?

    ??? $(if <condition>,<then-part>,<else-part>)

    ?

    可見, if 函數可以包含“ else ”部分,或是不含。即 if 函數的參數可以是兩個,也可以是三個。 <condition> 參數是 if 的表達式,如果其返回的為非空字符串,那么這個表達式就相當于返回真,于是, <then-part> 會被計算,否則 <else-part> 會被計算。

    ?

    if 函數的返回值是,如果 <condition> 為真(非空字符串),那個 <then-part> 會是整個函數的返回值,如果 <condition> 為假(空字符串),那么 <else-part> 會是整個函數的返回值,此時如果 <else-part> 沒有被定義,那么,整個函數返回空字串。

    ?

    所以, <then-part> <else-part> 只會有一個被計算。

    ?

    ?

    六、 call 函數

    ?

    call 函數是唯一一個可以用來創建新的參數化的函數。你可以寫一個非常復雜的表達式,這個表達式中,你可以定義許多參數,然后你可以用 call 函數來向這個表達式傳遞參數。其語法是:

    ?

    ??? $(call <expression>,<parm1>,<parm2>,<parm3>...)

    ?

    make 執行這個函數時, <expression> 參數中的變量,如 $(1) $(2) $(3) 等,會被參數 <parm1> <parm2> <parm3> 依次取代。而 <expression> 的返回值就是 call 函數的返回值。例如:

    ??? reverse =? $(1) $(2)

    ??? foo = $(call reverse,a,b)

    那么, foo 的值就是“ a b ”。當然,參數的次序是可以自定義的,不一定是順序的,如:

    ?

    ??? reverse =? $(2) $(1)

    ??? foo = $(call reverse,a,b)

    此時的 foo 的值就是“ b a ”。

    ?

    ?

    七、 origin 函數

    origin 函數不像其它的函數,他并不操作變量的值,他只是告訴你你的這個變量是哪里來的?其語法是:

    ?

    ??? $(origin <variable>)

    ?

    注意, <variable> 是變量的名字,不應該是引用。所以你最好不要在 <variable> 中使用“ $ ”字符。 Origin 函數會以其返回值來告訴你這個變量的“出生情況”,下面,是 origin 函數的返回值 :

    ?

    undefined

    ????? 如果 <variable> 從來沒有定義過, origin 函數返回這個值“ undefined ”。

    ?

    default

    ????? 如果 <variable> 是一個默認的定義,比如“ CC ”這個變量,這種變量我們將在后面講述。

    ?

    environment

    ????? 如果 <variable> 是一個環境變量,并且當 Makefile 被執行時,“ -e ”參數沒有被打開。

    ?

    file

    ????? 如果 <variable> 這個變量被定義在 Makefile 中。

    ?

    command line

    ????? 如果 <variable> 這個變量是被命令行定義的。

    ?

    override

    ????? 如果 <variable> 是被 override 指示符重新定義的。

    ?

    automatic

    ????? 如果 <variable> 是一個命令運行中的自動化變量。關于自動化變量將在后面講述。

    ?

    這些信息對于我們編寫 Makefile 是非常有用的,例如,假設我們有一個 Makefile 其包了一個定義文件 Make.def ,在 Make.def 中定義了一個變量“ bletch ”,而我們的環境中也有一個環境變量“ bletch ”,此時,我們想判斷一下,如果變量來源于環境,那么我們就把之重定義了,如果來源于 Make.def 或是命令行等非環境的,那么我們就不重新定義它。于是,在我們的 Makefile 中,我們可以這樣寫:

    ?

    ??? ifdef bletch

    ??? ifeq "$(origin bletch)" "environment"

    ??? bletch = barf, gag, etc.

    ??? endif

    ??? endif

    ?

    當然,你也許會說,使用 override 關鍵字不就可以重新定義環境中的變量了嗎?為什么需要使用這樣的步驟?是的,我們用 override 是可以達到這樣的效果,可是 override 過于粗暴,它同時會把從命令行定義的變量也覆蓋了,而我們只想重新定義環境傳來的,而不想重新定義命令行傳來的。

    ?

    ?

    八、 shell 函數

    ?

    shell 函數也不像其它的函數。顧名思義,它的參數應該就是操作系統 Shell 的命令。它和反引號“ ` ”是相同的功能。這就是說, shell 函數把執行操作系統命令后的輸出作為函數返回。于是,我們可以用操作系統命令以及字符串處理命令 awk sed 等等命令來生成一個變量,如:

    ?

    ??? contents := $(shell cat foo)

    ?

    ??? files := $(shell echo *.c)

    ?

    注意,這個函數會新生成一個 Shell 程序來執行命令,所以你要注意其運行性能,如果你的 Makefile 中有一些比較復雜的規則,并大量使用了這個函數,那么對于你的系統性能是有害的。特別是 Makefile 的隱晦的規則可能會讓你的 shell 函數執行的次數比你想像的多得多。

    ?

    ?

    九、控制 make 的函數

    ?

    make 提供了一些函數來控制 make 的運行。通常,你需要檢測一些運行 Makefile 時的運行時信息,并且根據這些信息來決定,你是讓 make 繼續執行,還是停止。

    ?

    $(error <text ...>)

    ?

    ??? 產生一個致命的錯誤, <text ...> 是錯誤信息。注意, error 函數不會在一被使用就會產生錯誤信息,所以如果你把其定義在某個變量中,并在后續的腳本中使用這個變量,那么也是可以的。例如:

    ?

    ??? 示例一:

    ??? ifdef ERROR_001

    ??? $(error error is $(ERROR_001))

    ??? endif

    ?

    ??? 示例二:

    ??? ERR = $(error found an error!)

    ??? .PHONY: err

    ??? err: ; $(ERR)

    ?

    ??? 示例一會在變量 ERROR_001 定義了后執行時產生 error 調用,而示例二則在目錄 err 被執行時才發生 error 調用。

    ?

    $(warning <text ...>)

    ?

    ???? 這個函數很像 error 函數,只是它并不會讓 make 退出,只是輸出一段警告信息,而 make 繼續執行。

    ?


    posted on 2006-09-23 00:30 dreamstone 閱讀(991) 評論(0)  編輯  收藏 所屬分類: 利器

    主站蜘蛛池模板: 亚洲一本之道高清乱码| 亚洲图片一区二区| 免费观看一区二区三区| 久久国产亚洲精品无码| 午夜a级成人免费毛片| 一区二区3区免费视频| 亚洲精品美女在线观看| 国产一区二区三区在线免费| 男人j进入女人j内部免费网站| 亚洲Av综合色区无码专区桃色| 亚洲一区免费视频| 色屁屁在线观看视频免费| 国产亚洲精品va在线| 韩国日本好看电影免费看| 女人隐私秘视频黄www免费| 在线观看日本亚洲一区| 国产亚洲精品观看91在线| 在线jlzzjlzz免费播放| 91亚洲性爱在线视频| 久久精品一本到99热免费| 在线观看免费亚洲| 亚洲电影免费在线观看| 无码国产亚洲日韩国精品视频一区二区三区 | 精品国产成人亚洲午夜福利| 成人免费视频网站www| 久久www免费人成看国产片| 日日噜噜噜噜夜夜爽亚洲精品| 无人在线观看免费高清视频 | 和老外3p爽粗大免费视频| 国产成人精品日本亚洲专区6| 亚洲中文字幕第一页在线| 日本午夜免费福利视频| 亚洲av日韩av永久无码电影| 亚洲av色影在线| 中文字幕一精品亚洲无线一区| 波多野结衣久久高清免费 | 无码一区二区三区AV免费| 日韩免费观看一区| 久久久久久久久久久免费精品| 久久久久亚洲精品无码网址色欲| 亚洲av午夜精品无码专区|