makefile中的特殊符號及關鍵字
1.常見自動變量和含義
- * :表示目標文件的名稱,不包含目標文件的擴展名。
- + :表示所有的依賴文件,這些依賴文件之間以空格分開,按照出現的先後為順序,其中可能包含重復的依賴文件。
- < :表示依賴項中第一個依賴文件的名稱
- ? : 依賴項中,所有目標文件時間戳晚的文件(表示修改過),依賴文件間以空格分開
- @ :目標項中目標文件的名稱
- ^ :依賴項中,所有不重復的依賴文件,以空格分開。
2.預定義變量
Makefile中常用的變量及含義
AR | 生成靜態庫庫文件的程序名稱 | ar |
AS | 匯編編譯器的名稱 | as |
CC | C語言編譯器的名稱 | cc |
CPP | C語言預編譯器的名稱 |
$(CC) -E |
CXX | C++語言編譯器的名稱 | g++ |
FC | FORTRAN語言編譯器的名稱 | f77 |
RM | 刪除文件程序的名稱 | rm -f |
ARFLAGS | 生成靜態庫庫文件程序的選項 | 無默認值 |
ASFLAGS | 匯編語言編譯器的編譯選項 | 無默認值 |
CFLAGS | C語言編譯器的編譯選項 | 無默認值 |
CPPFLAGS | C語言預編譯器的編譯選項 | 無默認值 |
CXXFLAGS | C++語言編譯器的編譯選項 | 無默認值 |
FFLAGS | FORTRAN語言編譯器的編譯選項 | 無默認值 |
3.設置搜索路徑
指定需要搜索的目錄, make 會自動找到指定文件的目錄並添加到文件上。
VPATH = path1:path2:...
4.遞歸make
對於規模比較大的程序,需要多個人在多個目錄下進行開發。如果只用一個 Makefile 來維護就會比較麻煩,因此可以在每個目錄下建立自己的 Makefile ,然後在總控 Makefile 中調用子目錄的 Makefile 文件。
目錄結構如下:
.
├── add
│ ├── add_float.c
│ ├── add.h
│ ├── add_int.c
│ └── Makefile
├── main.c
├── Makefile
└── sub
├── Makefile
├── sub_float.c
├── sub.h
└── sub_int.c
1.遞歸調用的方式
add:
cd add && $(MAKE)
它等價於
add:
$(MAKE) -C add
2.總控Makefile
CC = gcc CFLAGS = -O2 TARGET = cacu export OBJSDIR = $(shell pwd)/objs $(TARGET):$(OBJSDIR) main.o $(MAKE) -C add $(MAKE) -C sub $(CC) -o $(TARGET) $(OBJSDIR)/*.o $(OBJSDIR): mkdir -p $@ main.o:%.o:%.c $(CC) -c $< -o $(OBJSDIR)/$@ $(CFLAGS) -Iadd -Isub clean: -$(RM) $(TARGET) -$(RM) $(OBJSDIR)/*.o
如果總控 Makefile 中的一些變量需要傳遞給下層的 Makefile,可以使用 export 命令。如:
export OBJSDIR = ./objs
3.子目錄Makefile的編寫
Add 目錄下的 Makefile 如下:
OBJS = add_int.o add_float.o all:$(OBJS) $(OBJS):%.o:%.c $(CC) -c $< -o $(OBJSDIR)/$@ $(CFLAGS) clean: $(RM) $(OBJS)
Sub 目錄下的 Makefile 如下:
OBJS = sub_int.o sub_float.o all:$(OBJS) $(OBJS):%.o:%.c $(CC) -c $< -o $(OBJSDIR)/$@ $(CFLAGS) clean: $(RM) $(OBJS)
Makefile 中的函數
1.獲取匹配模式的文件名wildcard
這個函數的功能是查找當前目錄下所有符合模式 PATTERN 的文件名,其返回值是以空格分割的、當前目錄下的所有符合模式 PATTERN 的文件名列表。其原型如下:
$(wildcard PATTERN)
例如,如下模式返回當前目錄下所有擴展名位 .c 的文件列表。
$(wildcard *.c)
2.模式替換函數patsubst
這個函數的功能是查找字符串 text 中按照空格分開的單詞,將符合模式 pattern 的字符串替換成 replacement。 Pattern 中的模式可以使用通配符, % 代表 0 個到 n 個字符,當 pattern 和 replacement 中都有 % 時,符合條件的字符將被 replacement 中的替換。函數的返回值是替換後的新字符串。其原型如下:
$(patsubst pattern, replacement, text)
例如,需要將 C 文件替換為 .o 的目標文件可以使用如下模式:
$(patsubst %.c, %.o, add.c)
上面的模式將 add.c 字符串作為輸入,當擴展名為 .c 時符合模式 %.c ,其中 % 在這裏代表 add,替換為 add.o,並作為輸出字符串。
$(patsubst %.c, %.o, $(wildcard *.c))
輸出的字符串將當前擴展名為 .c 的文件替換成 .o 的文件列表。
3.循環函數foreach
這個函數的原型為:
$(foreach VAR, LIST, TEXT)
函數的功能為 foreach 將 LIST 字符串中一個空格分割的單詞,先傳給臨時變量 VAR ,然後執行 TEXT 表達式, TEXT 表達式處理結束後輸出。其返回值是空格分割表達式 TEXT 的計算結果。
例如,對於存在 add 和 sub 的兩個目錄,設置 DIRS 為 "add sub ./" 包含目錄 add、sub 和當前目錄。表達式 $(wildcard $(dir)/*.c) ,可以取出目錄 add 和 sub 及當前目錄中的所有擴展名為 .c 的C語言源文件:
DIRS = sub add ./
FILES = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
利用上面幾個函數對原有的 Makefile 文件進行重新編寫,使新的 Makefile 可以自動更新各個目錄下的C語言源文件:
CC = gcc CFLAGS = -O2 -Iadd -Isub TARGET = cacu DIRS = sub add . FILES = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c)) OBJS = $(patsubst %.c, %.o, $(FILES)) $(TARGET):$(OBJS) $(CC) -o $(TARGET) $(OBJS) clean: -$(RM) $(TARGET) -$(RM) $(OBJS)
以上內容來源於:
http://www.cnblogs.com/OpenShiFt/
感謝分享!
1 #該文件用於當前目錄下的c文件均為一個單獨的程序 2 #後續可修改把目標文件通過參數指定 3 cc = gcc 4 #all:$(subst .c,.o,$(wildcard *.c)) 5 PROGS = client server 6 all: $(PROGS) 7 8 #%o:%.c 9 # gcc -o $@ $< 10 %: %.c 11 $(cc) $(CFLAGS) [email protected] -o $@ $(LDFLAGS) $(LDLIBS) 12 13 clean: 14 rm -f $(PROGS) $(TEMPFILES) *.o
以上的內容基本可以閱讀大部分makefile了。
更多關於makefiel函數的內容,下面的博文寫的更全面。
makefile中常用函數 - CSDN博客 https://blog.csdn.net/yangxuan0261/article/details/52060582
makefile中的特殊符號及關鍵字