參考原文http://blog.csdn.net/liang13664759/article/details/1771246/shell
Makefile介紹:ui
Makefile告訴make命令如何編譯和連接文件,規則:spa
一、若是這個工程沒有編譯過,那麼全部c文件都要編譯並連接.net
二、若是某幾個c文件被修改,那麼只編譯被修改的c文件,並連接目標程序code
三、若是頭文件被改變,那麼須要編譯引用了這幾個頭文件的c文件並鏈接目標程序。blog
target... : prerequisites...
command
...
...
說明:target 爲目標文件,能夠是obj,也能夠是可執行文件,還能夠是標籤(就是一個標識而已)get
prerequisites爲,target所須要的文件,也就是target依賴的文件it
command,make須要執行的命令(可任意shell命令以【Tab】鍵開始,多條命令能夠多行,也能夠「;」隔開置於一行)編譯
target的目標文件依賴於prerequisites中的文件,生成規則定義在command中。prerequisites中若是有一個以上的文件比target文件要新的話,command所定義的命令就會被執行,這是Makefile的規則,也是Makefile的核心。class
例如:一個工程3個頭文件,8個c文件。
原始Makefile
edit:main.o kbd.o command.o display.o/ insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o/ insert.o search.o files.o utils.o main.o:main.c defs.h cc -c main.c kbd.o:kbd.c defs.h command.h cc -c kbd.c command.o:command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o: insert.c defs.h buffer.h cc -c insert.c search.o:search.c defs.h buffer.h cc -c search.c files.o: files.c defs.h buffer.h command.h cc -c files.c utils.o: utils.c defs.h cc -c utils.c clean://只是一個標籤,其後沒有依賴,make命令並不會執行其後定義的命令 rm edit main.o kbd.o command.o display.o/ //僅當make clean顯示指出標籤名字,才執行其後面的命令 insert.o search.o files.o utils.o
默認方式下,只輸入make命令,那麼:
一、make會在當前目錄下找到名字叫作「Makefile」或「makefile」的文件。
二、若是找到,會找文件中的第一個目標文件(target),在上面例子中,他會找到「edit」文件,並將其做爲最終的目標文件
三、若是edit不存在,或是edit所依賴文件的修改時間要比edit文件新,那麼就會執行後面所定義的命令來生成edit文件
四、若是edit所依賴的.o文件不存在,那麼make會在當前文件中找到目標爲.o文件的依賴性,若是找到再根據那個規則生成.o文件
五、固然,c文件和h文件是存在的,因而make會生成.o文件,而後再用.o文件生成edit文件。
說明:make會一層一層地去找文件的依賴關係,直到編譯出第一個目標文件,在尋找過程當中,若是出現錯誤,好比最後被依賴的問文件找不到,那麼make就會直接退出並報錯;而對於所定義的命令的錯誤或是編譯不成功,make根本不理會。
因此,clean這種沒有被第一個目標文件直接或間接關聯,後面所定義的命令不會被自動執行。可是能夠顯示要make的執行,「make clean」。
編譯中,若是其中一個源文件被修改,file.c,那麼file.o會被從新編譯,因此file.o是新的文件,比edit要新,因此edit也會被從新鏈接。若是改變了「command.h」,那麼kbd.o、command.o和files.o都會被編譯,而且,edit會被從新鏈接。
objects=main.o kbd.o command.o display.o/ insert.o search.o files.o utils.o edit:$(objects) cc -o edit $(objects) main.o:main.c defs.h cc -c main.c ...... clean: rm edit $(objects)
只要make看到一個.o文件,他會自動把.c文件加到依賴關係中,若是make找到一個whatever.o,那麼whatever.c就會是whatever.o的依賴文件。而且cc -c whatever.c也會被推導出來,因而
make的 "隱晦規則"
objects = main.o kbd.o command.o display.o/ insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) main.o:defs.h kbd.o:defs.h command.h command.o: defs.h command.h display.o : defs.h buffer.h insert.o: defs.h buffer.h search.o: defs.h buffer.h files.o: defs.h buffer.h command.h utils.o: defs.h .PHONY:clean //.PHONY表示clean是個僞目標文件 clean: rm edit $(objects)
objects = main.o kbd.o command.o display.o/ insert.o search.o files.o utils.o edit: $(objects) cc -o edit $(objects) $(objects): defs.h kbd.o command.o files.o: command.h display.o insert.o search.o files.o: buffer.h .PHONY:clean clean: r m edit $(objects)
makeMakefile都用該寫一個清空目標文件(.o和執行文件)的規則,不只便於從新編譯,也利於保持文件的清潔。
通常:
clean:
rm edit $(objects)
更爲穩健的作法:
.PHONY: clean
clean:
-rm edit $(objects)//rm前面的-,表示就算某些文件出現問題也繼續作後面的事情。
說明:clean的規則不要放在文件的開頭,否則就會成爲make的默認目標。通常,clean都是放在文件的最後。