Makefile系列之規則

2021-08-22 19:44:34 字數 3282 閱讀 3257

×××××××××××××××××××××××××××××××××××××

×××××××××××××××××××××××××××××××××××××

語法

targets:prerequisites (; command)

command

...

targets : 目標,可以是空格分開的多個檔案,也可使用萬用字元;

prerequitites : 依賴,根據依賴更新後是否需要重建目標,將依賴分為兩種,用「|」進行分割,「需要|不需要」,把更新後不需要重建目標的依賴稱為「order-only」依賴;

command : 有兩種風格,可以與目標和依賴在同一行,用分號分割,或者在下一行,並必須以【tab】字元開始;

目錄搜尋

vpath:是個變數,指定了make執行時當前makefile中所有檔案的搜尋路徑,包括規則的依賴檔案和目標檔案,定義時通過冒號「:」將多個目錄分開,如libs_dirs = /lib:/usr/lib:/usr/local/lob;

vpath:是個關鍵字,可以為不同型別的檔案指定不同的搜尋路徑,使用時通過模式字元「%」進行匹配,但是模式匹配所指定的檔案僅僅指在makefile中出現的相應型別的檔案,(如:%.h 並不包含原始檔中包含的標頭檔案所在的路徑,其需要在編譯時通過 gcc 的 -i 選項進行指定),使用格式如下,為所有符合模式「pattern」的檔案指定搜尋目錄「directory」,多個目錄使用空格或冒號分開 :

vapth pattern directories;
gpath:變數,如果目標是通過目錄搜尋得到的完整路徑名,且該目標所在的目錄出現在gpath所定義的目錄列表中,那麼重建目標時將在該目錄下進行,而不是在makefile所在的目錄下進行;

-iname: 若在依賴檔案列表中存在這種格式的依賴檔案,make將根據name在當前系統中依次搜尋可提供的共享庫、靜態庫。

搜尋時的搜尋順序是: makefile檔案所在的目錄 => vpath、vpath指定搜尋目錄 => 對於用-i方式引入的庫檔案依賴,還會搜尋庫檔案的預設目錄/lib、/usr/lib、prefix/lib;

通過搜尋得到的檔名可能是包含路徑資訊的完整檔名,可能並不是規則中列出的檔名,為了保證規則中能正確的使用依賴檔案,規則的命令列中必須使用自動化變數來代表依賴檔案;

特殊目標

(0).特殊的普通目標

clean:

rm *.o temp

特點:

i). 規則的目標不是乙個存在的檔案;

ii). 沒有依賴或命令;

可能產生的問題:

i). 目標名字可能與當前工作目錄下的實際檔案名字衝突。

(a).若目標名字與當前工作目錄下的實際名字不衝突時,即此時當前工作目錄下不存在同名的檔案,且該目標沒有依賴,此時make便會通過執行命令去「完成目標的建立」(建立和更新目標是規則的命令部分被賦予的理論上應有的功能),所以此時該規則的命令會被成功執行;

(b).若衝突時,由於規則沒有任何依賴,且目標的同名檔案已存在,所以目標會被認為是最新的,因此該規則的命令將不會被執行,此時的結果便與我們定義該規則的初衷相悖;

ii). 當目標名字與當前工作目錄下的實際檔名不衝突時,及目標的同名檔案不存在時,make在執行時會試去查詢可用的隱含規則來建立它,雖然最終並不會找到合適的隱含規則去建立,但是試圖查詢可用的隱含規則的過程是不可避免的,這會影響make的執行效率;

(1).強制目標

特點:i).「force」 是乙個強制目標,但是在gnu make中應避免使用,盡量通過 .phony 的方式來代替;

ii).強制目標本身不是乙個真正的檔案,並且規則沒有命令或依賴,該規則中的目標總被認為是最新的(無論強制目標的同名檔案是否存在,沒有依賴的規則的目標檔案總被認為是最新的,但規則的命令是否會被執行取決與同名檔案則是否存在)

iii).當強制目標作為某個規則的依賴時,由於依賴總被認為是最新的,則以強制目標作為依賴的規則中所定義的命令總會被執行,因此可使用強制目標作為上述(0)中的特殊的普通目標的依賴,來達到與定義成偽目標同樣的效果,如下:

clean:force

rm *.o temp

(2).偽目標

偽目標不是乙個真正的檔名,可以沒有命令或依賴,也可以都有,通過指定規則的目標來完成某一功能的一系列命令,通過 .phony 進行定義,如下:

.phony:clean

clean:

rm *.o temp

特點:

i).避免makefile中的目標和工作目錄下的實際檔名衝突;

ii).提高make執行效率,對於宣告為偽目標的規則,make執行時不會試圖去為它查詢隱含規則來建立它;

iii).無論目標檔案是否存在,其規則中的命令總會被無條件執行。一般不將偽目標作為乙個目標的依賴,因為該規則每次在檢查時,偽目標的命令都會被執行;

iv).偽目標可以有自己的依賴(可以是乙個或者多個檔案或偽目標)。如果乙個偽目標作為另外乙個偽目標的依賴時,作為依賴的偽目標會被認為時目標偽目標的子例程來處理,即其時目標偽目標必須要執行的部分;

v).偽目標可以實現並行處理,而替代shell語句中的for語句(它是順序執行);

(3).空目標檔案

是偽目標的乙個變種,這個目標可以使乙個存在的檔案,但檔案的內容我們並不關心,它只是用來記錄上一次執行此命令的時間,通常是在規則的所有命令列的最後使用touch命令來更新目標檔案的時間戳,以記錄此規則命令的最後執行時間,如下:

print : foo.c bar.c

lpr -p $?

touch print (print 檔案存在,但其只是為了記錄規則最近執行的時間戳)

Makefile學習之規則

1 ifeq debug true 2 cc gcc g 生成debug版本,才可以生成除錯資訊,對程式進行除錯,3else 4 cc gcc 5 endif 6.phony all clean 偽目標,讓編譯器無條件執行,每次都會執行 7 all test 這裡預設編譯test,hello是不編譯...

Makefile常用規則

表示目標檔案 表示所有的依賴檔案 表示第乙個依賴檔案 表示比目標還要新的依賴檔案列表 同樣表示所有依賴目標的集合 不去除重複的依賴目標 makefile變數使用 或者 或 者 來呼叫,如果是shell變數,則需要使用 來引用。一種變數替換方法 src a.c b.c obj src o c 變數賦值...

makefile編寫規則

目標 要生成的目標檔案 依賴 目標檔案由哪些檔案生成 命令 通過執行該命令由依賴檔案生成目標 代表目標 代表全部依賴 第一依賴 第一變化的依賴 2020 8 3 wildcard可以進行檔案匹配 patsubst 內容的替換 makefile的變數 代表目標 代表全部依賴 第一依賴 第一變化的依賴 ...