makefile文件編寫


一、編譯和鏈接

  編譯:

一般來說,無論是C還是C++,首先要把源文件編譯成中間 代碼文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即Object File,這個動 作叫做編譯(compile)。然后再把大量的Object File合成執行文件,這個動作叫作鏈接(link)

  編譯時,編譯器需要的是語法的正確,函數與變量的聲明的正確。對於后者,通常是你需要告訴編譯器頭文 件的所在位置(頭文件中應該只是聲明,而定義應該放在C/C++文件中),只要所有的語法正確,編譯器就 可以編譯出中間目標文件。一般來說,每個源文件都應該對應於一個中間目標文件( .o 文件或 .obj 文件)。

  鏈接:

  鏈接時,主要是鏈接函數和全局變量。所以,我們可以使用這些中間目標文件( .o 文件或 .obj 文件)來鏈接我們的應用程序。鏈接器並不管函數所在的源文件,只管函數的中間目標文件 (Object File),在大多數時候,由於源文件太多,編譯生成的中間目標文件太多,而在鏈接時需要明顯 地指出中間目標文件名,這對於編譯很不方便。所以,我們要給中間目標文件打個包,在Windows下這種包 叫“庫文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。

  總結一下,源文件首先會生成中間目標文件,再由中間目標文件生成執行文件。在編譯時,編譯器只檢測程 序語法和函數、變量是否被聲明。如果函數未被聲明,編譯器會給出一個警告,但可以生成Object File。 而在鏈接程序時,鏈接器會在所有的Object File中找尋函數的實現,如果找不到,那到就會報鏈接錯誤碼 (Linker Error),在VC下,這種錯誤一般是: Link 2001錯誤 ,意思說是說,鏈接器未能找到 函數的實現,你需要指定函數的Object File。

 


 

二、makefile編寫

  1. 如果這個工程沒有編譯過,那么我們的所有c文件都要編譯並被鏈接。

  2. 如果這個工程的某幾個c文件被修改,那么我們只編譯被修改的c文件,並鏈接目標程序。

  3. 如果這個工程的頭文件被改變了,那么我們需要編譯引用了這幾個頭文件的c文件,並鏈接目標程序。

 

 2.1 makefile規則:

target ... : prerequisites ...
    command
    ...
    ...

 

 

  target

   可以是一個object file(目標文件),也可以是一個執行文件,還可以是一個標簽(label)。對 於標簽這種特性,在后續的“偽目標”章節中會有敘述。

  prerequisites 

   生成該target所依賴的文件和/或target

  command

   該target要執行的命令(任意的shell命令)

這是一個文件的依賴關系,也就是說,target這一個或多個的目標文件依賴於prerequisites中的文件, 其生成規則定義在command中。

 

 2.1 makefile實例:

    

直接輸入命令make可以生成文件edit,刪除執行文件和所有的中間目標文件,那么,只要簡單地執行一下 make clean.

 

  聲明一個變量:

 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 make的隱晦規則,.PHONY表示clean是個目標偽文件。

穩健做法如下:

   

 

 

 .PHONY表示clean是一個“偽目標”。而在rm命令前面加上一個小減號的意思是,也許某些文件出現問題,但不要管,繼續做后面的事。

 

 2.2 makefile包含東西:

  Makefile包含顯式規則、隱晦規則、變量定義、文件指示和注釋

  1. 顯式規則。顯式規則說明了如何生成一個或多個目標文件。這是由Makefile的書寫者明顯指出要生成的 文件、文件的依賴文件和生成的命令。

  2. 隱晦規則。由於我們的make有自動推導的功能,所以隱晦的規則可以讓我們比較簡略地書寫 Makefile,這是由make所支持的。

  3. 變量的定義。在Makefile中我們要定義一系列的變量,變量一般都是字符串,這個有點像你C語言中的 宏,當Makefile被執行時,其中的變量都會被擴展到相應的引用位置上。

  4. 文件指示。其包括了三個部分,一個是在一個Makefile中引用另一個Makefile,就像C語言中 的include一樣;另一個是指根據某些情況指定Makefile中的有效部分,就像C語言中的預編譯#if一 樣;還有就是定義一個多行的命令。有關這一部分的內容,我會在后續的部分中講述。

  5. 注釋。Makefile中只有行注釋,和UNIX的Shell腳本一樣,其注釋是用 #字符,這個就 像C/C++中的 // 一樣。如果你要在你的Makefile中使用 # 字符,可以用反斜杠進行 轉義,如: \# 。

 

Makefile中的命令必須要以TAB鍵開始。

 

2.3 make的工作方式:

  1. 讀入所有的Makefile。

  2. 讀入被include的其它Makefile。

  3. 初始化文件中的變量。

  4. 推導隱晦規則,並分析所有規則。

  5. 為所有的目標文件創建依賴關系鏈。

  6. 根據依賴關系,決定哪些目標要重新生成。

  7. 執行生成命令。


 

三、makefile書寫規則

  文件搜尋:

  

 

 

 上面的定義指定兩個目錄,“src”和“../headers”,make會按照這個順序進行搜索。目錄由“冒號”分隔 。(當然,當前目錄永遠是最高優先搜索的地方)

另一個設置文件搜索路徑的方法是使用make的“vpath”關鍵字(注意,它是全小寫的),這不是變量,這是 一個make的關鍵字,這和上面提到的那個VPATH變量很類似,但是它更為靈活。它可以指定不同的文件在不 同的搜索目錄中。這是一個很靈活的功能。它的使用方法有三種:

  

 

 

 

 

 

參考文獻:

https://seisman.github.io/how-to-write-makefile/introduction.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM