1. GNU的make工作時(shí)的執(zhí)行步驟入下:
1. 讀入所有的Makefile。
2. 讀入被include的其它Makefile。
3. 初始化文件中的變量。
4. 推導(dǎo)隱晦規(guī)則,并分析所有規(guī)則。
5. 為所有的目標(biāo)文件創(chuàng)建依賴關(guān)系鏈。
6. 根據(jù)依賴關(guān)系,決定哪些目標(biāo)要重新生成。
7. 執(zhí)行生成命令。
2. .PHONY 指明后面為偽目標(biāo)
.SILENT 相當(dāng)于make的-s參數(shù),在執(zhí)行前不顯示要執(zhí)行的命令
.IGNORE 相當(dāng)于make的-i參數(shù),當(dāng)檢測(cè)到錯(cuò)誤,繼續(xù)執(zhí)行其他命令
make –n 參數(shù),讀取規(guī)則并顯示,但是不執(zhí)行
gcc –M 由編譯器自動(dòng)生成依賴關(guān)系
3. 判斷:ifeq/ ifneq/ ifdef/ ifndef
ifeq ($(CC),gcc)
$(CC) -o foo $(objects) $(libs_for_gcc)
else
$(CC) -o foo $(objects) $(normal_libs)
endif
4. 可識(shí)別的后綴指的是特殊目標(biāo)“.SUFFIXES”的所有依賴的名字。通過(guò)給特殊目標(biāo)“SUFFIXES”添加依賴來(lái)增加一個(gè)可被識(shí)別的后綴:
.SUFFIXES: .hack .win
它所實(shí)現(xiàn)的功能是把后綴“.hack”和“.win”加入到可識(shí)別后綴列表的末尾。
如果需要重設(shè)默認(rèn)所有的可識(shí)別后綴,可以這樣來(lái)實(shí)現(xiàn):
.SUFFIXES: #刪除所有已定義的可識(shí)別后綴
.SUFFIXES: .c .o .h #重新定義
5. -include filename,包含文件
6. -M 生成文件的關(guān)聯(lián)的信息,這樣就可以知道源代碼文件里面關(guān)聯(lián)了哪些它所依賴的頭文件。
-MD 跟-M相當(dāng),但是輸出導(dǎo)入到.d文件中,如gcc -MD test.c,剛輸出的依賴關(guān)系存放在test.d文件里。
7. $@ 代表規(guī)則中的目標(biāo)文件名
$< 規(guī)則的第一個(gè)依賴文件名。如果是隱含規(guī)則,則它代表通過(guò)目標(biāo)指定的第一個(gè)依賴文件。
$^ 規(guī)則的所有依賴文件列表,使用空格分隔。
8. 我們可以使用最終萬(wàn)用規(guī)則來(lái)實(shí)現(xiàn)。例如:在調(diào)試Makefile時(shí)(可能一些源文件還沒(méi)有完成),我們所關(guān)心的是Makefile中規(guī)則的正確執(zhí)行,而不關(guān)心源文件的內(nèi)容。
%::
touch $@
9. 列出當(dāng)前目錄下所有符合模式“PATTERN”格式的文件名。
返回值:空格分割的、存在當(dāng)前目錄下的所有符合模式“PATTERN”的文件名。
$(wildcard *.c)
返回值為當(dāng)前目錄下所有.c源文件列表。
10. 目標(biāo)總會(huì)被認(rèn)為是最新的。就是說(shuō):這個(gè)規(guī)則一旦被執(zhí)行,make就認(rèn)為它的目標(biāo)已經(jīng)被更新過(guò)
clean: FORCE
rm $(objects)
FORCE:
11. subsystem:
cd subdir && $(MAKE)
其等價(jià)于規(guī)則:
subsystem:
$(MAKE) -C subdir
規(guī)則中“$(MAKE)”是對(duì)變量“MAKE" 的引用。第一個(gè)規(guī)則命令的意思是:進(jìn)入子目錄,然后在子目錄下執(zhí)行make。第二個(gè)規(guī)則時(shí)用了make的“-C”選項(xiàng),同樣是首先進(jìn)入子目錄而后再執(zhí)行make。
12. -w選項(xiàng)
在多級(jí)make遞歸調(diào)用過(guò)程中,選項(xiàng)“-w”或者“--print-directory”可以讓make在開始編譯一個(gè)目錄之前和完成此目錄的編譯之后給出相應(yīng)的提示信息
以下是自己寫的一個(gè)Makefile,目錄結(jié)構(gòu)為模塊目錄下存在inc、src、obj三個(gè)目錄。由于用到了隱式規(guī)則,存在目錄的一些限制,當(dāng)前巴該Makefile放到子目錄obj下:
====================================================
vpath %.c ../src
INCLUDE=../inc
CC=gcc
CFLAGS=-g -I$(INCLUDE)
TARGET=lib.a
DEPENDFILE=depend.dep
SRC_DIR=$(wildcard ../src/*.c)
OBJS=$(patsubst %.c,%.o,$(notdir $(SRC_DIR)))
all:$(TARGET)
$(TARGET):$(DEPENDFILE) $(OBJS)
ar -crv $@ $(OBJS)
$(DEPENDFILE):
$(CC) -M -I$(INCLUDE) $(SRC_DIR) > $@
.PHONY:clean
clean:
rm -rf $(TARGET) *.o $(DEPENDFILE)
-include depend.*
====================================================