makefile學習筆記1

Makefile的作用: makefile關係到整個過程的編譯規則,makefile制定了一系列規則來指定哪些文件先編譯,哪些文件後編譯,哪些編譯需要重新編譯,甚至進行更復雜的功能操作,makefile就像一個shell腳本一樣,也可以執行操作系統的命令,也就是實現“自動化編譯”,一旦寫好,只需要一個make命令,整個工程就會完全自動編譯,極大的提高了軟件開發的效率。

首先了解程序的編譯和鏈接。編譯器需要的是語法正確,函數與變量的聲明正確,只要語法正確,編譯器就可以編譯出中間文件。每個源文件都應該對應於一箇中間目標文件。把源文件編譯成中間代碼文件(linux下是.o文件,Windows下是.obj文件)。鏈接主要是鏈接函數和全局變量。利用中間目標文件鏈接應用程序。
源文件首先會生成中間目標文件,再由中間目標文件生產執行文件。在編譯時,編譯器只檢測程序語法,和函數是否被聲明,如果沒有被聲明只會給出警告,仍然可以生產object file。在連接程序時,鏈接器會在所有的object file中尋找函數的實現,如果找不到會報鏈接錯誤。

寫一個 makefile告訴make命令如何編譯和鏈接所指的文件。規則是:

         1.如果這個工程沒有編譯過,那麼我們的所有C文件都要編譯並被鏈接。
  2.如果這個工程的某幾個C文件被修改,那麼我們只編譯被修改的C文件,並鏈接目標程序。
   3.如果這個工程的頭文件被改變了,那麼我們需要編譯引用了這幾個頭文件的C文件,並鏈接目標程序。

makefile規則

<target> : <prerequisites> 
[tab]  <commands>
     target:目標文件,可以是中間目標文件也可以是執行文件,還可以是標籤(Label)(依賴生產的)
     prerequisites:源文件,要生成的目標文件所需要的文件或目標。(被依賴的)
     command:make需要執行的命令。

這是一個文件的依賴關係,也就是說,target這一個或多個的目標文件依賴於prerequisites中的文件,其生成規則定義在command中。說白一點就是說,prerequisites中如果有一個以上的文件比target文件要新的話,command所定義的命令就會被執行。這就是Makefile的規則。

      每個*.o文件都對應一組依賴文件。而這些.o文件又是執行文件的依賴文件。
      定義好依賴關係後,後續一行定義瞭如何生產目標文件的操作系統命令。注意要以Tab鍵作爲開頭。
      make會比較targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新或者targets文件不存在,make會執行後續的命令。

     clean不是一個文件,而是一個動作名字。

make在默認方式下如何執行
1.make會在當前目錄下找名字叫Makefile 或makefile的文件。
2.如果找到,它會找文件的第一個目標文件(tagart),並把文件作爲最終的目標文件。
3.如果目標文件不存在,或者目標文件所依賴的.o文件修改時間要比目標文件新,那麼會執行後續定義的命令語句生成目標文件。
4.如果目標所依賴的.o文件也存在,那麼make會在當前文件中找目標爲.o文件的依賴性,如果找到則再根據那一個規則生成.o文件
5.如果C文件和H文件都存在,那麼make會生成.o文件。然後.o文件聲明make的終極任務,也就是執行目標文件了。

$(objects)的使用
make自動推到——>隱晦規則

.PHONY:clean表示clean是一個僞目標


.PHONY : clean
clean :
-rm edit $(objects)


rm前面加一個”-” 表示某些文件出現問題。不用管,繼續執行後面的命令。

makefile文件裏主要包含五個東西:顯示規則,隱晦規則,變量定義,文件指示和註釋。

顯示規則:又makefile書寫者明顯指出要生成的文件,以及文件要依賴的文件,生成的命令。
隱晦規則:主要是makefile有自動推導的功能。
變量的定義:變量一般是字符串,當makefile被執行時,其中的變量會被擴展到相應的引用位置上。
註釋:makefile中只有註釋行。用“#”字符。

最好用Makefile命名Makefile文件。

Makefile文件中可以引用其他的Makefile:
使用include關鍵字可以把別的Makefile包含進來,include語法是:
include
其中filename可以是當前操作系統shell的文件模式以爲可以包含路徑和通配符。

                                  -include<filename>
                                                        表示無論include過程中出現什麼錯誤,都不要報錯而是繼續執行。

環境變量MAKEFILE
如果你的當前環境中定義了環境變量MAKEFILES,那麼,make會把這個變量中的值做一個類似於include的動作。這個變量中的值是其它的Makefile,用空格分隔。只是,它和include不同的是,從這個環境變中引入的Makefile的“目標”不會起作用,如果環境變量中定義的文件發現錯誤,make也會不理。
建議不要使用這個環境變量,因爲只要這個變量一被定義,那麼當你使用make時,所有的Makefile都會受到它的影響。

make的工作方式:
一:第一個階段
1. 讀入所有的Makefile。
2. 讀入被include的其它Makefile。
3. 初始化文件中的變量。
4. 推導隱晦規則,並分析所有規則。
5. 爲所有的目標文件創建依賴關係鏈。
二:第二個階段
6. 根據依賴關係,決定哪些目標要重新生成。
7. 執行生成命令。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章