編寫乙個makefile

2021-08-16 23:43:47 字數 3345 閱讀 8430

什麼是makefile?

對於大多數的windows程式設計師來講,makefile可能不是那麼重要,因為windows的ide都為程式設計師做好了這個工作。但是在linux下程式設計,會不會寫makefile,從側面上說明乙個人是否具備完成大型工程的能力。

makefile的作用

makefile是用來自動編譯和鏈結的,乙個大的工程會有很多的檔案組成,每乙個檔案的改變都會導致工程的重新鏈結,但不一定所有的檔案都需要重新編譯。此時,我們的makefile就可以完成自動化編譯,一旦寫好,乙個make命令,就可以完成整個工程的編譯。

那什麼是編譯?

無論是c、c++,都要先將原始檔編譯成中間**檔案,在windows下是.obj檔案,在unix、linux下是.o檔案,這個過程就被稱作為編譯

鏈結

鏈結的主要是鏈結函式和全域性變數,此時,鏈結器不管函式所在的原始檔,只管函式的中間目標檔案(.obj/.o檔案)。

但在大多數的情況下,由於原始檔過多,編譯生產的目標檔案也太多,而在鏈結的時候需要明顯的指出中間目標檔案,這就很不方便了。所以,我們需要給中間檔案打包,在windows下的這種包叫做「庫檔案」(.lib),在unix/linux下是archive file(.a)

清楚了程式編譯和鏈結的過程,我們下來介紹makefile

make命令執行的時候需要乙個makefile檔案,告訴make如何去編譯和鏈結程式

執行make命令的規則:

如果這個工程沒有編譯過,那麼我們所有的c檔案都要編譯並被鏈結

如果這個工程的某幾個c檔案被修改,那麼我們只編譯被修改的c檔案,並鏈結目標程式

如果這個工程的標頭檔案被修改,我們需要編譯引用了這幾個標頭檔案的c檔案,並鏈結生成目標程式

makefile的規則

target…:prerequisites…

command

… target:目標檔案,可以是.o檔案,也可以是執行檔案,或者是乙個標籤

prerequisites:依賴檔案,就是要生成那個target所需要的檔案或目標檔案(.c和.h檔案),依賴關係的實質是說明了目標檔案由哪些檔案生成

command:make需要執行的命令(可以是任意的shell命令)

注意:

在定義好依賴關係後,後序的一行定義了如何生成目標檔案的操作命令,必須以tab鍵開頭。

我們現在編寫乙個簡單的makfile

make的工作過程

我們在編譯乙個工程的時候,輸入make命令,此時,作業系統會做如下工作:

1、make會在當前目錄找」makefile」或」makefile」檔案

2、如果找到,它會找檔案中的第乙個目標檔案(上述例子中的01檔案),並把這個檔案作為最終的目標檔案

3、如果01檔案不存在,或者是01檔案所依賴的後面的.o檔案的檔案修改時間要比01檔案這個檔案新,那麼,就會執行後面所定義的命令來生成01檔案

4、如果01所依賴的01.o檔案也不存在,那麼make就會在當前檔案中找到目標為.o檔案的依賴性,如果找到再根據那乙個規則生成.o檔案

5、make會生成.o檔案,然後再用.o檔案生命make的終極任務,也就是執行01檔案了

make會一層一層的找檔案的依賴關係,直到最終編譯出第乙個目標檔案,在找尋的過程中,如果有錯誤,make就會直接退出,並報錯。但是對於定義的命令,出錯或編譯不成功,make不做處理。make只管檔案的依賴性。

makefile裡有什麼呢?

makefile主要包含五個東西:顯示規則、隱晦規則、變數定義、檔案指示、注釋

1、顯示規則:顯示說明如何生成乙個或多個目標檔案,需要由生成的檔案、檔案的依賴檔案、生成的命令構成

2、隱晦規則:make具有自動推導的功能,所以隱晦規則可以讓我們比較粗糙的書寫makefile

3、變數定義:在makefile中我們會定義一系列的變數,變數一般都是字串,類似於c語言中的巨集,當makefile被執行時,其中的變數都會被擴充套件到相應的引用位置上

4、檔案指示

在makefile中引用另乙個makefile,類似於c語言中的include

根據某種情況指定makefile中的有效部分,類似於c語言中的#if

定義乙個多行的命令

5、注釋

只有行注釋,注釋用」#」字元

make的工作方式:

1、讀入所有的makefile

2、讀入被include的其他makefile

3、初始化檔案的變數

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

5、為所有的目標檔案建立依賴關係

6、依據依賴關係,決定哪些目標需要重新生成

7、執行生成命令

偽目標

我們舉個例子:

clean:

rm *.o temp

其中,」clean」目標就是乙個偽目標,以」make clean」來使用該目標。

偽目標不是乙個檔案,只是乙個標籤,由於偽目標不是乙個檔案,所以make無法生成它的依賴關係和決定它是否要執行,我們只有通過這個目標才能讓其生效。

偽目標的取名不能與檔名重名,所以我們定義了乙個特殊的標記」.phony」來顯示地指明乙個目標是「偽目標」。

.phony:clean

clean:

rm *.o temp

多目標

有時候我們的多個目標同時依賴乙個檔案,並且生成的命令大體類似。我們可以將這些目標合併起來,可以使用乙個自動化變數」$@」,表示目前規則中所有目標的集合

舉例說明:

text1 text2:text.c

gcc -c $@

等價於:

text1:text.g

gcc -c text1.c

text2:text.g

gcc -c text2.c

乙個通用Makefile的編寫

我們在linux環境下開發程式,少不了要自己編寫makefile,乙個稍微大一些的工程下面都會包含很多.c的原始檔。如果我們用gcc去乙個乙個編譯每乙個原始檔的話,效率會低很多,但是如果我們可以寫乙個makefile,那麼只需要執行乙個make就ok了,這樣大大提高了開發效率。但是makefile的...

乙個簡單的makefile的編寫

標頭檔案 part.h cpp檔案 包含part.h part.cpp cpp檔案 包含part.h partmain.cpp makefile編寫如下 main partmain.o part.o g o main partmain.o part.o partmain.o partmain.cpp...

編寫乙個簡單通用的makefile

author 李超 date 2012 05 06 縱然makefile 的規則還是相當多的,編寫乙個大規模的軟體,良好的 makefile 架構是方便維護程式編譯的關鍵。學習 makefile 的時間週期還是比較長的,為了寫出規範的 需要在很短的時間內編寫乙個 makefile 這裡給給出乙個 m...