Makefile之大型工程專案子目錄Makefile的一種通用寫法

工程師WWW發表於2014-01-02

管理Linux環境下的大型專案,能夠有一個智慧的Build子系統會起到事半功倍的效果,本文描述Linux環境下大型工程專案子目錄Makefile的一種通用寫法,使用該方法,當該子目錄內的檔案有增刪時無需對Makefile進行改動,可以說相當的智慧。下面先貼程式碼(為了減少篇幅,一些非關鍵的程式碼被去掉):


  1. ROOTDIR = .  
  2.   
  3. EXE_DIR = ./bin  
  4. CFLAGS = -I$(INCLUDE_DIR) -I$(LIB_INC) -Wall  
  5. LFLAGS = -L$(LIB_DIR)  
  6.   
  7. objects := $(patsubst %.c,%.o,$(wildcard *.c))  
  8. executables := $(patsubst %.c,%,$(wildcard *.c))  
  9.   
  10. $(objects) : %.o: %.c  
  11.     $(CROSS_COMPILE)gcc -c $(CFLAGS) $< -o $@  
  12. all : $(executables)  
  13. $(executables) : $(objects)  
  14.     @mkdir -p ./bin$  
  15.     (CROSS_COMPILE)gcc $(CFLAGS) $< -o $(EXE_DIR)/$@ $(LFLAGS) $(LIBS)  
  16. clean:  
  17.     @rm -f *.o rm -f ./bin/*   
  18.     @rm -rf ./bin   
  19. 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的寫法就可以完全掌握了

相關文章