生活随笔
收集整理的這篇文章主要介紹了
makefile 学习(一)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、Makefile的基本規則 GNU make 規則: target ... :?prerequisites?...command........
target ?— 目標文件, 可以是Object File 也可以是可執行文件,還可也是標簽Label(標簽內容在“偽目標”章節); prerequisites —生成target所需的文件或目標; command —make需要執行的命令,可以是任何shell命令。 二、一個簡單的例子 創建一個名為count_word.c的文件,代碼如下 [cpp] ?view plaincopy
#include?<stdio.h> ?? extern ? int ?fee_count,?fie_count,?foe_count,?fum_count;?? extern ? int ?yylex(? void ?);?? ?? int ?main(? int ?argc,? char ?**?argv?){?? ????yylex(?);?? ????printf(?"%d?%d?%d?%d\n" ,?fee_count,?fie_count,?foe_count,?fum_count?);?? ????return (?0?);?? }?? 另外創建一個lexer.l文件,其中所有的空白均為tab鍵 [cpp] ?view plaincopy
???????? int ?fee_count?=?0;?? ????????int ?fie_count?=?0;?? ????????int ?foe_count?=?0;?? ????????int ?fum_count?=?0;?? %%?? fee?????fee_count++;?? fie?????fie_count++;?? foe?????foe_count++;?? fum?????fum_count++;?? 最后創建makefile文件,內容為: [cpp] ?view plaincopy
count_words:?count_words.o?lexer.o?-lfl?? ????????gcc?count_words.o?lexer.o?-lfl?-o?count_words?? count_words.o:?count_words.c?? ????????gcc?-c?count_words.c?? lexer.o:?lexer.c?? ????????gcc?-c?lexer.c?? lexer.c:?lexer.l?? ????????flex?-t?lexer.l?>?lexer.c?? clean:?? ????????rm?lexer.c?lexer.o?count_words.o?count_words?? 以上內容保存在Makefile或者是makefile都可以,直接輸入make命令就可以生成可執行文件count_words了; gcc -c count_words.c
flex -t lexer.l > lexer.c
gcc -c lexer.c
gcc count_words.o lexer.o -lfl -o count_words
如果要刪除執行文件和中間的目標文件,那么就執行一下make clean。注意1: ?當依賴關系定好后,下面一行就是如何生成目標文件的操作系統命令了,一定要以一個Tab鍵開頭。 另外,make會比較targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期比targets文件新,或者targets不存在,那么make就會執行這下面一行的系統命令。注意2:? clean不是一個文件,它是一個動作名,冒號后面什么都沒有,make就不會自動去找它的依賴性,也不會執行它后面的系統命令。因此,要執行clean就需要顯式的指出make clean。注意3:? 如果報錯,可能需要先安裝flex: [plain] ?view plaincopy
sudo?apt-get?install?flex?? 注意4:? 運行count_works后,它會回顯你的輸出并統計'fee','fie','foe','fum'的次數。結束統計需要按Ctrl+d,然后會輸出四個單詞出現的次數。 三、make 如何工作 默認方式
直接輸入make,則 make會在當前的目錄下找到名為“Makefile”或者“makefile”的文件。 如果找到,它會把文件中第一個target作為最終的目標文件(如上面例子中的count_words)。 首先,make會檢查目標count_words的prerequisite文件count_words.o, lexer.o 和 -lfl。 count_words.o通過編譯count_words.c生成 lexer.o通過編譯lexer.c 生成,但是lexer.c 并不存在,因此會繼續尋找lexer.c的生成方式,并找到了通過flex程序將lexer.l生成為lexer.c。 最后,make會檢查-lfl,-l是gcc的一個命令選項,表示將系統庫鏈接到程序。而"fl"對應的是libfl.a的庫。(GNU make 可以識別這樣的命令,當一個prerequisite是以這種-l<name>的形式表示出來的時候,make會自己搜索lib<name>.so的庫文件,如果沒找到則繼續搜索lib<name>.a的庫文件)。這里make找到的是/usr/lib/libfl.a文件,并將它與程序進行連接。 如果count_words文件不存在,或者count_words所依賴的后面的.o文件的修改時間比count_words本身更加新,那么,它會執行后面定義的命令來生成這個count_words文件。如果count_words所依賴的.o文件也不存在,那么make會繼續按照前面的方式生成.o文件。 找到相應的.c和.h,用來生成.o,然后再用.o完成make的最終任務。 關于依賴關系
make會一層一層的去找文件的依賴關系,最終編譯出第一個目標文件。 關于重新編譯
只要任何prerequisite 比 target新,那么這個目標文件就會被下面的命令重新生成。每一個命令都會被傳遞到shell中,并在自己的子shell里面執行。 關于錯誤
如果在尋找過程中出現錯誤,如文件找不到,則make會直接退出并報錯。對于所定義的命令錯誤或者編譯不成功,make是不會理會的,它只負責文件的依賴性。 四、變量使用 上面的例子可以看到,文件或者目標的名字幾乎都毫無例外的出現了至少兩次,甚至如果算上clean的內容,有些文件名出現了三次。然而,在一個大型的工程中這種情況會更加復雜,任何不經意的錯誤都會導致編譯失敗。為了讓makefile更容易維護,在makefile中我們可以使用變量,或者更確切的說是一個字符串,類似c語言中的宏。例如: [cpp] ?view plaincopy
CC?=?gcc?? object?=?lexer.o?count_words.o?? count_words:?$(object)?-lfl?? ????????$(CC)?$(object)?-lfl?-o?count_words?? count_words.o:?count_words.c?? ????????$(CC)?-c?count_words.c?? lexer.o:?lexer.c?? ????????$(CC)?-c?lexer.c?? lexer.c:?lexer.l?? ????????flex?-t?lexer.l?>?lexer.c?? clean:?? ????????rm?lexer.c?$(object)?count_words?? 五、自動推導依賴關系 GNU make可以根據.o文件的文件名自動推導出同名的.c文件并加入依賴關系,不需要我們手動注明。并且gcc -c也會被自動推導出來,于是我們的makefile就變成了 [cpp] ?view plaincopy
CC?=?gcc?? object?=?lexer.o?count_words.o?? count_words:?$(object)?-lfl?? ????????$(CC)?$(object)?-lfl?-o?count_words?? count_words.o:??? lexer.o:?? lexer.c:?lexer.l?? ????????flex?-t?lexer.l?>?lexer.c?? clean:?? ????????rm?lexer.c?$(object)?count_words?? 這種方法也叫“隱式規則”。 六、關于Clean 一個好習慣是每個makefile都要寫clean規則,這樣不僅可以方便重編譯,也有利于保持文件路徑的清潔。一般的風格是: [cpp] ?view plaincopy
clean:?? ????????rm?lexer.c?$(object)?count_words?? 但是,更為穩妥的做法是: [cpp] ?view plaincopy
.PHONY:?clean?? clean:?? ????????-rm?lexer.c?$(object)?count_words?? .PHONY表示clean是一個“偽目標”,而rm命令前面的減號則表示,不管出現什么問題都要繼續做后面的事情。 注意:clean規則不要放在makefile的開頭,不然就會變成make的默認目標了。
轉載于:https://www.cnblogs.com/nktblog/p/4027117.html
總結
以上是生活随笔 為你收集整理的makefile 学习(一) 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。