1. 程式人生 > >makefile學習筆記1

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. 執行生成命令。