1. 程式人生 > >makefile中的特殊符號及關鍵字

makefile中的特殊符號及關鍵字

目標 需要 編寫 ats www. 如果 符號 placement ace

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中的特殊符號及關鍵字