Makefile的一種通用寫法以及其中的字段含義

管理Linux環境下的C/C++大型項目,本文描述Linux環境下大型工程項目子目錄Makefile的一種通用寫法,使用該方法,當該子目錄內的文件有增刪時無需對Makefile進行改動,可以說相當的智能。

下面先貼代碼(爲減小篇幅,一些非關鍵的代碼被去掉,本方法的侷限是用於一個C文件生成一個可執行文件的場合):

ROOTDIR = .

EXE_DIR = ./bin
CFLAGS = -I$(INCLUDE_DIR) -I$(LIB_INC) -Wall
LFLAGS = -L$(LIB_DIR)

objects := $(patsubst %.c,%.o,$(wildcard *.c))
executables := $(patsubst %.c,%,$(wildcard *.c))

all : $(objects)
$(objects) :%.o : %.c
    @mkdir -p ./bin$
    $(CROSS_COMPILE)gcc -c $(CFLAGS) $< -o $@
    $(CROSS_COMPILE)gcc $(CFLAGS) $< -o $(subst .o, ,$(EXE_DIR)/$@) $(LFLAGS) $(LIBS)
clean:
    @rm -f *.o rm -f $(executables)
    @rm -rf ./bin 
distclean: clean

假如當前目錄裏面有a.c b.c兩個文件

      Makefile 裏的函數跟它的變量很相似——使用的時候,你用一個$符號跟左圓括號,函數名,空格後跟一列由逗號分隔的參數,最後用右圓括號結束。例如,在GNU Make裏有一個叫'wildcard' 的函數,它有一個參數,功能是展開成一列所有符合由其參數描述的文件名,文件間以空格間隔。像這個命令: 
 
    objects= $(wildcard *.c)    
 
  會產生一個所有以'.c' 結尾的文件列表(本例結果爲a.c b.c),然後存入變量objects裏。    
 
  另一個有用的函數是 patsubst ( patten substitude,匹配替換的縮寫)函數。它需要3個參數——第一個是一個需要匹配的式樣,第二個表示用什麼來替換它,第三個是一個需要處理由空格分隔的序列。我們將兩個函數合起來用:
 
objects := $(patsubst %.c,%.o,$(wildcard *.c))
 會被處理爲: 
objects := a.o b.o
 同理: 
executables := $(patsubst %.c,%,$(wildcard *.c))
 會被處理爲: 
executables := a b
 
%.o:所有以“.o”結尾的目標,也就是a.o b.o
 
依賴模式“%.c”:取模式“%.o”的%,也就是foo bar,併爲其加上.c後綴,即a.c,b.c
 

$<:表示所有依賴目標集,也就是a.c b.c
 
$@:表示目標集,也就是a.o b.o
 
命令前加@,表示在終端中不打印,如@mkdir -p ./bin
 
$(objects) : %.o: %.c 
        $(CROSS_COMPILE)gcc -c $(CFLAGS) $< -o $@
 

即可翻譯爲: 


a.o b.o : a.c b.c    $(CROSS_COMPILE)gcc -c $(CFLAGS) (a.c b.c) -o (a.o b.o)
 
明白了這些,這種Makefile的寫法就可以完全掌握了。
 
注:當前目錄直接make的兩種寫法:

1:如果在當前目錄中直接make的話使用下列代碼:

#General Purpose Makefile by guoqingbo
                          
objects := $(patsubst %.c,%.o,$(wildcard *.c))  
executables := $(patsubst %.c,%,$(wildcard *.c))  
                          
all :  $(objects)
$(objects) : %.o: %.c 
    gcc -c $< -o $@
    gcc $< -o $(subst .o, ,$@) 
clean :
    @rm -rf *.o *~
    @rm -rf ${executables}
 .PHONY : clean

2:後來發現下列代碼也可以有相同效果,難道使用了什麼默認規則,還不是很明白,先記錄下來:

#General Purpose Makefile by guoqingbo  
                            
executables := $(patsubst %.c,%,$(wildcard *.c))
                            
all : $(executables)

clean :  
    @rm -rf *.o *~  
    @rm -rf ${executables}  
.PHONY : clean

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章