1. 程式人生 > >寫一個簡單的 Makefile

寫一個簡單的 Makefile

參考來源:https://www.cnblogs.com/owlman/p/5514724.html

每次改動一個原始碼檔案以後,如果都要編譯一次所有原始碼,會浪費很多時間。Makefile 可以只編譯更新過的原始碼,節省時間。

比如:g++ main_solve.cpp qab.cpp -o Pandawarrior.x

可以寫 Makefile, 內容為:

Pandawarrior.x : main_solve.cpp qab.cpp

  g++ -o Pandawarrior.x main_solve.cpp qab.cpp

第一句表示,Pandawarrior.x 依賴 main_solve.cpp 和 qab.cpp,如果其中任意一個更新了,就執行第二行(命令),即編譯得到新的 Pandawarrior.x

編輯好 Makefile 以後,打 make 就可以按照新寫的 Makefile 編譯或者重編譯。

 

為了方便改動,可以用字元代替 Pandawarrior.x 等等名字:

compiler = g++

excutable = Pandawarrior.x

source = main_solve.cpp qab.cpp

$(excutable) : $(source)

  $(compiler) -o $(excutable) $(source)

 

這樣寫以後,只要 main_solve.cpp,qab.cpp 有一個有變化,就全部重新編譯一遍,和每次編輯以後打

g++ main_solve.cpp qab.cpp -o Pandawarrior.x

沒有任何區別。所以並沒有發揮 Makefile 的長處。可以改寫為:

compiler = g++

excutable = Pandawarrior.x

src = main_solve.cpp qab.cpp

obj = main_solve.o qab.o

$(excutable) : $(obj)

  $(compiler) -o $(excutable) $(obj)

main_solve.o : main_solve.cpp

  $(compiler) -c main_solve.cpp

qab.o : qab.cpp

  $(compiler) -c qab.cpp

這樣,如果改動 qab.cpp,重新編譯時只會再次編譯

g++ -c qab.cpp

g++ -o Pandawarrior.x main_solve.o qab.o

不會重新編譯 main_solve.cpp,所以節省了時間。

但是這麼寫的話,太囉嗦了,如果 *.cpp 特別多,就會特別長,所以可以簡寫:

compiler = g++

excutable = Pandawarrior.x

headfile = $(shell find ./ -name "*.h")

src = $(shell find ./ -name "*.cpp")

obj = $(src:%.cpp=%.o)

$(excutable) : $(obj)

  $(compiler) -o $(excutable) $(obj)

%.o : %.cpp $(headfile)

  $(compiler) -c $< -o [email protected]

其中,headfile = $(shell find ./ -name "*.h") 裡的 shell 是 Makefile 的一個函式,意思是執行 shell 中的命令,返回結果,所以這句意思是 headfine = "*.h",即資料夾下的所有 "*.h" 檔案

$(src:%.cpp=%.o) 是一個“字元替換函式”,意思是將 src 中的所有 *.cpp 檔名換成相應的 *.o 檔名。

%.o : %.cpp 是一個“模式規則”,表示所有 *.o 檔案都依賴於與之同名的 *.cpp 檔案。

$< 表示依賴關係中的第一個,即 %.cpp,[email protected] 表示目標,即 %.o

 

後面還可以加一句

clean:

  rm -rf $(obj) $(excutable)

加了以後,可以打 make clean,即清除所有 *.o,以及 Pandawarrior.x 檔案。

 

我已經按這個教程,給我的 PandasCommute 寫了一個 Makefile,在 https://github.com/luyi07/PandasCommute.git,驗證了一下,是成功的。

 GNU Make Manual.pdf 我已下載,供下次查閱。