編寫Makefile總結

以下的記錄都是本人在編寫和閱讀Makefile過程中所遇到疑問。


1. makefile中的shell腳本語句需要在目標裏纔有效

否則無效被忽略或者發生錯誤。

2. makefile中執行shell條件判斷語句出現錯誤:“syntax error : unexpected end of file”

如下所示:

DEL_DIR:
@if [ -d /tmp/test ]; then rm -rf /tmp/test fi

執行make時,出錯:“syntax error : unexpected end of file”
解決辦法:在fi前加入";",則OK,即:

DEL_DIR:
@if [ -d /tmp/test ]; then rm -rf /tmp/test; fi

3. Makefile中的變量

 具體使用詳見:
http://wiki.ubuntu.org.cn/%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile:%E4%BD%BF%E7%94%A8%E5%8F%98%E9%87%8F
寫得非常詳細和具體。

說下目標變量

前面我們所講的在Makefile中定義的變量都是“全局變量”,在整個文件,我們都可以訪問這些變量。當然,“自動化變量”除外,如“$<”等這種類量的自動化變量就屬於“規則型變量”,這種變量的值依賴於規則的目標和依賴目標的定義。

當然,我也同樣可以爲某個目標設置局部變量,這種變量被稱爲“Target-specific Variable”,它可以和“全局變量”同名,因爲它的作用範圍只在這條規則以及連帶規則中,所以其值也只在作用範圍內有效。而不會影響規則鏈以外的全局變量的值。

其語法是:

<target ...> : <variable-assignment>;

<target ...> : overide <variable-assignment>

<variable-assignment>;可以是前面講過的各種賦值表達式,如“=”、“:=”、“+=”或是“?=”。第二個語法是針對於make命令行帶入的變量,或是系統環境變量。

這個特性非常的有用,當我們設置了這樣一個變量,這個變量會作用到由這個目標所引發的所有的規則中去。如:

prog : CFLAGS = -g
prog : prog.o foo.o bar.o
        $(CC) $(CFLAGS) prog.o foo.o bar.o

prog.o : prog.c
        $(CC) $(CFLAGS) prog.c

foo.o : foo.c
        $(CC) $(CFLAGS) foo.c

bar.o : bar.c
        $(CC) $(CFLAGS) bar.c

在這個示例中,不管全局的$(CFLAGS)的值是什麼,在prog目標,以及其所引發的所有規則中(prog.o foo.o bar.o的規則),$(CFLAGS)的值都是“-g”

4. shell命令的執行

 規則中,當目標需要被重建時。此規則所定義的命令將會被執行,如果是多行命令,那麼每一行命令將在一個獨立的子shell進程中被執行(就是說,每一行命令的執行是在一個獨立的shell進城中完成)。因此,多行命令之間的執行是相互獨立的,相互之間不存在依賴(多條命令行的執行爲多個相互獨立的進程)。

在Makefile中書寫在同一行中的多個命令屬於一個完整的shell命令行,書寫在獨立行的一條命令是一個獨立的shell命令行。因此:在一個規則的命令中,命令行“cd”改變目錄不會對其後的命令的執行產生影響。就是說其後的命令執行的工作目錄不會是之前使用“cd”進入的那個目錄。如果要實現這個目的就不能把“cd”和其後的命令放在兩行來書寫。而應該把這兩條命令寫在一行上,用分號分隔。這樣它們纔是一個完整的shell命令行。如:

 

foo : bar/lose

cd bar; gobble lose > ../foo

 

如果希望把一個完整的shell命令行書寫在多行上,需要使用反斜槓(\)來對處於多行的命令進行連接,表示他們是一個完整的shell命令行。例如上例我們以也可以這樣書寫:

foo : bar/lose

cd bar;  \

gobble lose > ../foo

 

make對所有規則命令的解析使用環境變量“SHELL”所指定的那個程序,在GNU make中,默認的程序是“/bin/sh”。

不像其他絕大多數變量,它們的值可以直接從同名的系統環境變量那裏獲得。make的環境變量“SHELL”沒有使用系統環境變量的定義。因爲系統環境變量“SHELL”指定那個程序被用來作爲用戶和系統交互的接口程序,它對於不存在直接交互過程的make顯然不合適。在make的環境變量中“SHELL”會被重新賦值;它作爲一個變量我們也可以在Makefile中明確地給它賦值(指出解釋程序的名字,當明確指定時需要使用完整的路徑名。如“/bin/sh”),變量“SHELL”的默認值是“/bin/sh”。

5. 待補充

 待補充



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章