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