當我們寫程式過程中存在多個文件之間有複雜的包含關係時,若修改了其中一個源文件,就重新編譯所有文件,一般是不必要的,並且當文件很多時,就顯得非常笨拙。所有包含該文件的文件需要重新編譯,而其它無關係的文件則不需要編譯,但往往判斷的這個過程會很令程式員頭疼,並且一不小心就會出現某些需要重新編譯的文件被遺漏 ...
當我們寫程式過程中存在多個文件之間有複雜的包含關係時,若修改了其中一個源文件,就重新編譯所有文件,一般是不必要的,並且當文件很多時,就顯得非常笨拙。所有包含該文件的文件需要重新編譯,而其它無關係的文件則不需要編譯,但往往判斷的這個過程會很令程式員頭疼,並且一不小心就會出現某些需要重新編譯的文件被遺漏的情況,這樣就會使程式無法正常工作。
make就可以解決上述問題,它會在必要時編譯所有受改動影響的源文件。
但是make自身是不能完成這項任務的,我們需要為其提供一個文件,告訴它如何去處理文件之間的關係,這個文件就是makefile文件。
就是在makefile文件中按照一定的格式把要生成的文件在編譯時所需要的源文件以及編譯規則寫出來。這樣,make會根據makefile文件按照規則在需要時重新編譯所有受改動影響的源文件。可以同時存在多個不同的makefile文件分別管理項目的不同部分。makefile文件一般和其它源文件放在同一目錄下。
make -f makefile文件名
-f 選項就是指定將哪個文件作為makefile文件。如果沒有使用-f選項,標準版本make命令將首先在當前目錄下找名字為makefile的文件,找不到會繼續查找Makefile的文件。(特殊的GNU Make則會按照GNUmakefile、makefile、Makefile的順序搜索)
makefile文件由一組依賴關係和規則構成。完整的makefile文件例子會在後面列出。
makefile中的每個依賴關係由 一個目標文件(一般為要創建的可執行文件)和一組該目標所依賴的源文件組成。
makefile文件依賴關係的寫法()如下:
mypro: main.o myc1.o
main.o: main.c a.h b.h
myc1.o: myc1.c b.h
mypro1: mypro1.c
最開始是目標文件名稱,然後一個冒號,後面是目標文件所依賴的源文件(冒號和後面的源文件之間以及不同源文件之間用空格或製表符間隔)
特別需要註意的是,雖然makefile文件中已經寫入了多個目標文件,但是如果只是這樣執行 make 則make命令只會創建makefile文件中的第一個目標,即mypro
若要一次性創建makefile中的所有文件,需要在makefile文件的第一個目標定義為all(我們稱之為偽目標),即:
all: mypro mypro1
mypro: main.o myc1.o
main.o: main.c a.h b.h
myc1.o: myc1.c b.h
mypro1: mypro1.c
或者執行make命令時,加上all參數 : make all
makefile文件的規則:
規則就是指當make創建目標文件時的方式,比如在編譯myc1.o文件時,如何進行編譯(如可能需要指定頭文件的目錄等)。
在此應特別註意:makefile文件中的 空格 和 製表符 是有區別的。規則所在的行必須以 製表符 開頭,不可以用空格。並且makefile文件中不能以空格結尾,可能會使make命令執行失敗(這屬於歷史遺留問題)
另外,makefile文件中可以使用巨集定義。
下麵舉例完整的makefile文件:
定義一個命名為Makefile123的makefile文件
#cat Makefile123
all: mypro
#This is a makefile
#the compiler
CC = gcc
#the path
INCLUDE = .
#where to install
INSTDIR = /usr/local/bin
install: mypro
@if [ -d $(INSTDIR) ]; \
then \
cp mypro $(INSTDIR) &&\
chmod a+x $(INSTDIR)/mypro &&\
chmod og-w $(INSTDIR)/mypro &&\
echo "Installed in $(INSTDIR)" ;\
else \
echo "Sorry, $(INSTDIR) does not exist" ; \
fi
mypro: main.o c1.o
gcc -o mypro main.o a.o
main.o: main.c m.h
$(CC) -I$(INCLUDE) -c main.c
c1.o: c1.c
$(CC) -c c1.c
clean:
-rm main.o c1.o
1、make中的特殊符號:
-
告訴make命令忽略所有錯誤
@ 告訴make執行某條命令前不要將該條命令顯示在準輸出上
# 是makefile中的註釋符號
CC = gcc 以及 INCLUDE = . 和INSTDIR = /usr/local/bin 是makefile中自行建立的的巨集定義,引用方式為$(CC)、$(INCLUDE)和$(INSTDIR)
2、註意all只指定了一個目標mypro,所以只執行 make -f Makefile123時,則預設只創建目標mypro
我們可以看到在Makefile123文件中存在兩個目標clean 和 install。
install依賴於mypro ,執行make -f Makefile123 install時,make會自行判斷創建文件的正確順序
該文件中目標install的規則由一串shell腳本命令組成,此處註意,make命令在執行規則時會調用一個shell,並且每個規則都使用一個新的shell,所以在代碼結尾加上反斜杠\,使得所有shell腳本命令在邏輯上處於一行。 &&符號保證保證前面的命令執行成功後面的才會繼續執行。
clean目標後面沒有依賴文件,則執行 make -f Makefile123 clean時,clean對應的規則總會執行,而不是像其他目標一樣只有在依賴文件發生變化時執行規則。