日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

makefile 学习(一)

發布時間:2025/3/14 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 学习(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。