|
本博文是在學習了《GNU Make中文手冊》后記錄下來的自己的關于自動產生makefile依賴的語句的理解,向大家分享。 《GNU make中文手冊》中的相關章節(jié)見一下鏈接: http://blog.csdn.net/gmpy_tiger/article/details/51849257 ======================================================================================== 為了理解自動產生依賴的代碼,必須先掌握這兩個基礎又有點偏的知識點: 1、Makefile 中,一個文件可以作為多個規(guī)則的目標(多個規(guī)則中只能有一個規(guī)則定義命令)。這種情況時,以這個文件為目標的規(guī)則的所有依賴文件將會被合并成此目標一個依賴文件列表,當其中任何一個依賴文件比目標更新(比較目標文件和依賴文件的時間戳)時,make 將會執(zhí)行特定的命令來重建這個目標。 舉個例子: 有如下的makefile: foo.o : defs.hbar.o : defs.h test.h foo.o : config.h 等效于: foo.o : defs.h config.h bar.o : defs.h test.h 就是把相同foo.o目標的規(guī)則(最多只允許一個規(guī)則有命令,其他規(guī)則只能有依賴)合并所有的依賴。 2、在linux 的命令sed中,有這么一個規(guī)則(模式替換單獨的單詞,見《Linux命令行與shell腳本編程大全》): sed編輯器用圓括號來定義替代模式的子字符串,替代字符由反斜杠和數組組成。 很難理解是吧,舉個例子你就懂了。 echo "maybe this is a test" | sed 's/\ (this\ ) is a \ (test\ )/Is \1 really \2 /g' 輸出: maybe Is this really test 關于腳本的echo,管道,sed的替換命令s等基礎我就不講了,自己百度學習。這里我要講的是,用“()”小括號括起來的被替換內容,可以在替換內容上用“\數字”代替,直接動態(tài)引用,省去重復輸入的麻煩。例如上面的例子,\1代表this,\2代表test,整個sed命令的意思是把 this is a test 替換為 Is this really test ps:因為小括號在正則表達式中有意義,因此需要轉義,因此是\ (...\ )而不是(...) ======================================================================================== 廢話不多說,先直接上我自己寫得自動產生依賴的代碼(與《GNU Make中文手冊》有些許出入,會寫linux腳本的就會發(fā)現,修改的部分無傷大雅): %.d : %.c gcc -MM $< > $@.$ $ $ $; \ (1) rm -f $@.$ $ $ $ (3) ps:網頁的排版問題,為了看的直觀做了修改,使用時請把四個$以及\ (和\ )之間的空格去掉,下同 繼續(xù)以例子講解: 源代碼如下(helloworld.c): #include <stdio.h> (1): 用gcc -MM helloworld.c的輸出結果是: helloworld.o: helloworld.c test.h 因此(1)行代碼 gcc -MM $< > $@.$ $ $ $; \ (1) 的作用,就是生成helloworld.o.xxxx的臨時文件,文件內寫得是"helloworld.o: helloworld.c test.h" ps:在第一行的代碼里涉及到makefile的自動化變量$<、$@和linux腳本的重定向,自行百度,不再講解。 (2): 第二行的代碼 sed 's/\ ($*\ )\.o/\1.o $@/g' < $@.$ $ $ $ > $@;
\ (2) 參考本博文上文的基礎知識2,其中,$*是自動化變量,在這里指的是:helloworld。$@也是自動化變量,在這里指的是helloworld.d。 這行代碼可以理解為: sed 's/helloworld.o/helloworld.o helloworld.d/g' < $@.$ $ $ $ >$@ ps:其中的兩個< 、>為linux腳本的重定向,自己百度學習。 因此,實際的處理結果是把第(1)行代碼的結果 helloworld.o: helloworld.c test.h 轉換為: helloworld.o
helloworld.d: helloworld.c test.h 并把轉換的結果保存到helloworld.d文件中。 (3): 第二行代碼其實就已經完成任務了,第三行代碼僅僅是刪除第一行代碼創(chuàng)建的臨時文件$@.$$$$。在此不再詳述。 ======================================================================================= 自動產生依賴的代碼就這樣理解,那怎么使用呢? 先看看上面代碼生成的結果: helloworld.o helloworld.d: helloworld.c test.h 保存在helloworld.d文件中 要使用,除了上面的代碼之外,只需要加一句 include helloworld.d 其實就相當于把代碼自動生成的 helloworld.o helloworld.d: helloworld.c test.h包含在makefile中。 包含上了helloworld.d的作用有兩條 1、因為要包含helloworld.d,當搜索不到有helloworld.d文件時,就會自動匹配上文產生依賴的代碼,自行生成helloworld.d,當然,當helloworld.c或者test.h修改后,由于helloworld.d已經過時,也會重新生成helloworld.d 2、helloworld.o的依賴會合并上helloworld.c test.h(參考本博文上文的基礎知識1),從而實現了自動產生依賴 ======================================================================================= 總結起來,我對上面helloworld源碼寫的makefile如下: CC = gcc helloworld.d如下: helloworld.o helloworld.d: helloworld.c test.h
|
|
|