看了“跟我一起寫Makefile”, 總結了一下Makefile的一些用法, 調試Makefile的過程中的c源文件和Makefile中間文件請查看我的資源:http://download.csdn.net/detail/yunjingguang/7271301
1. Makefile的作用
makefile 就像一個 Shell腳本一樣,其中也可以執行操作系統的命令。
makefile 帶來的好處就是——“自動化編譯”,一旦寫好,只需要一個 make命令,整個工程完全自動編譯,極大的提高了軟件開發的效率。make是一個命令工具,是一個解釋 makefile中指令的命令工具,一般來說,大多數的 IDE都有這個命令,比如:Delphi的 make,VisualC++的 nmake,Linux下 GNU的 make。可見,makefile都成爲了一種在工程方面的編譯方法。
2. Makefile的介紹
2.1 gcc的編譯步驟
先建立一些頭文件和源文件:add.c add.h comAM.c comAM.h main.c minus.c minus.h,其中包含關係是:comAM.c包含add.h和minus.h,main.c包含所有的頭文件。
如果使用gcc編譯出可執行程序,需要下面的步驟:
上面這些源文件將作爲示例,作用於整個介紹中。
2.2 Makefile的基本寫法
2.2.1 Makefile的規則
在講述這個 Makefile 之前,還是讓我們先來粗略地看一看 Makefile的規則。
target ... : prerequisites ...
command
...
...
target 也就是一個目標文件,可以是 Object File,也可以是執行文件。還可以是一個標籤(Label),對於標籤這種特性,在後續的“僞目標”章節中會有敘述。
prerequisites 就是,要生成那個 target所需要的文件或是目標。
command 也就是 make需要執行的命令。(任意的 Shell命令)
這是一個文件的依賴關係,也就是說,target這一個或多個的目標文件依賴於 prerequisites中的文件,其生成規則定義在 command中。說白一點就是說,prerequisites 中如果有一個以上的文件比 target文件要新的話,command所定義的命令就會被執行。這就是 Makefile的規則。也就是 Makefile中最核心的內容。
下面是一個簡單的Makefile,可以在console上輸入make,就可以自動編譯出最後的執行文件:
在默認的方式下,也就是我們只輸入 make命令。那麼,
1、make會在當前目錄下找名字叫“Makefile”或“makefile”的文件。
2、如果找到,它會找文件中的第一個目標文件(target),在上面的例子中,他會找到“testM”這個文件,並把這個文件作爲最終的目標文件。
3、如果 testM文件不存在,或是 testM所依賴的後面的 .o 文件的文件修改時間要比 testM這個文件新,那麼,他就會執行後面所定義的命令來生成 testM這個文件。
4、如果 testM所依賴的.o文件也存在,那麼 make會在當前文件中找目標爲.o文件的依賴性,如果找到則再根據那一個規則生成.o文件。(這有點像一個堆棧的過程)
10、當然,你的 C文件和 H文件需要是存在的,於是 make會生成 .o文件,然後再用文件生成 make的終極任務,也就是執行文件 testM了。
2.2.2 使用變量
在Makefile中,可以將重複使用的字符串定義爲變量,這樣可以簡化Makefile,如下:
2.2.3 Makefile的自動推導
GNU 的 make很強大,它可以自動推導文件以及文件依賴關係後面的命令,於是我們就沒必要去在每一個[.o]文件後都寫上類似的命令,因爲,我們的 make 會自動識別,並自己推導命令。
只要 make 看到一個[.o]文件,它就會自動的把[.c]文件加在依賴關係中,如果 make 找到一個 whatever.o,那麼 whatever.c,就會是 whatever.o的依賴文件。並且 cc -c whatever.c也會被推導出來,於是,我們的 makefile再也不用寫得這麼複雜。我們的是新的 makefile又出爐了。
2.2.4 清空目標文件的規則
每個 Makefile 中都應該寫一個清空目標文件(.o和執行文件)的規則,這不僅便於重編譯,也很利於保持文件的清潔。這是一個“修養”。一般的風格都是:
.PHONY : clean
clean :
-rm .....
在rm命令前的“-”號表示,即使某些文件出現了問題,也不要管,繼續做後面的事情。 .PHONY是聲明後面的目標(clean)爲僞目標,僞目標特點:
1.用.PHONY聲明,爲了避免和文件重名;
2.總是被執行,不用判斷依賴的文件和目標的時間;
3.運行僞目標: make僞目標,例如:make clean;
2.2.5 Makefile中的“%:”使用(靜態模式)
“%.o:%.c”表示將$(OBJ)中所有以.o結尾的目標文件轉換爲以.c結尾的依賴文件。
2.2.6 文件搜索
一個設置文件搜索路徑的方法是使用 make 的“vpath”關鍵字(注意,它是全小寫的),
這不是變量,這是一個 make的關鍵字,這和 VPATH變量很類似,但是它更爲靈活。它可以指定不同的文件在不同的搜索目錄中。這是一個很靈活的功能。它的使用
方法有三種:
1、vpath <pattern> <directories>
爲符合模式<pattern>的文件指定搜索目錄<directories>。
2、vpath <pattern>
清除符合模式<pattern>的文件的搜索目錄。
3、vpath
清除所有已被設置好了的文件搜索目錄。
vapth 使用方法中的<pattern>需要包含“%”字符。
“%”的意思是匹配零或若干字符,例如,
“%.h”表示所有以“.h”結尾的文件。<pattern>指定了要搜索的文件集,而<directories>則指定了<pattern>的文件集的搜索的目錄。例如:
vpath %.h ../headers
該語句表示,要求 make在“../headers”目錄下搜索所有以“.h”結尾的文件。(如果某文件在當前目錄沒有找到的話)
我們可以連續地使用 vpath 語句,以指定不同搜索策略。如果連續的 vpath語句中出現了相同的<pattern>,或是被重複了的<pattern>,那麼,make會按照 vpath 語句的先後順序來執行搜索。如:
vpath %.c foo
vpath % blish
vpath %.c bar
其表示“.c”結尾的文件,先在“foo”目錄,然後是“blish”,最後是“bar”目錄。
調整目錄結構,所有頭文件放到include/下,所有的源文件放到src下:
Makefile修改如下:
1.vpath指定各種文件的存放目錄;
2.$<:表示所有的依賴文件, $@:表示所有的目標文件;
3.$(addprefix a, b):是Makefile中的函數,意義:給b中的每一個單詞加一個a的字符串前綴;
這樣一個相對專業和簡潔的Makefile就完成了,如果再有新的源文件,直接在OBJ後面加對應的目標文件就可以了。
2.3 Makefile的其他技巧
2.3.1 多個目錄夾的編譯
示例Makefile:
1.$(addsuffix a, b): Makefile的函數,意義:將b中的每一個單詞都加一個a的字符串後綴;
2.在某個目錄下執行make:make -C目錄;
3.$(basename a): Makefile的函數,意義:取出a中每個文件名“.”前的字符串,例如:$(basename add.c minus.c ):結果就是add minus;
4.連續執行多條命令:當你期望後面的命令在前面命令執行後的基礎上再執行,那麼命令之間需要用“;”隔開;
2.3.2 變量傳遞
如果你希望Makefile某個變量可以傳到下一級的Makefile中可以用exprot聲明,例如: