天天看點

多目錄下多檔案 makefile編寫

前面已經分享了單目錄項下多檔案的makefile的編寫,現在來看看多目錄下多檔案makefile的編寫;

        在做項目時,一般檔案都會分幾個目錄來存放;基本的是  include/  bin/ src/ obj/ lib/ tools/,這幾個檔案;我先說下我的檔案存放目錄,用ls -R可以檢視到所有檔案:./include/common.h    ./src/main.c    ./src/printStatus.c  就三個檔案,其中*.c 檔案都依賴于 *.h檔案;

        同樣的先上第一版makefile:

CC=gcc  

objects=obj/main.o obj/printStatus.o  

bin/main:$(objects)  

   $(CC) -o bin/main $(objects)  

obj/main.o:src/main.c include/common.h  

   $(CC) -o obj/main.o -c src/main.c -Iinclude  

obj/printStatus.o:src/printStatus.c include/common.h  

   $(CC) -o obj/printStatus.o -c src/printStatus.c -Iinclude  

clean:  

   rm -rf $(objects) bin/main  

        上面的makefile就是gcc指令的拼湊起來的,下面來分享下比較通用的多目錄下的makefile;

        在看多目錄的makefile時,先來了解下幾個函數和變量;

函數:

        wildcard 這是擴充通配符函數,功能是展開成一列所有符合由其參數描述的文 件名,檔案間以空格間隔;比如:羅列出src下的所有.c檔案:$(wildcard ${SRC}/*.c)

        patsubst 這是比對替換函數, patsubst ( 需要比對的檔案樣式,比對替換成什麼檔案,需要比對的源檔案)函數。比如:用src下的*.c替換成對應的 *.o檔案存放到obj中:$(patsubst  %.c, ${OBJ}/%.o, $(notdir $(SOURCE)))

        notdir 這是去除路徑函數,在上面patsubst函數中已經使用過,去除SOURCE中檔案的所有目錄,隻留下檔案名;

變量:

        $@:表示目标檔案;一般是在規則中這麼用:gcc  -o $@  $(object);

        $^:表示所有依賴檔案;一般是在規則中這麼用:gcc -o $@  $^  ;用所有依賴檔案連結成目的檔案;

        $<:表示第一個依賴檔案;在規則中使用:gcc -o $@ -c $< ;其實這個時候就是每個依賴檔案生成一個目的檔案;

第二版makefile

#把所有的目錄做成變量,友善修改和移植   

BIN = ./bin  

 SRC = ./src  

 INC = ./include  

 OBJ = ./obj  

#提前所有源檔案(即:*.c檔案)和所有中間檔案(即:*.o)  

 SOURCE = $(wildcard ${SRC}/*.c)  

 OBJECT = $(patsubst %.c,${OBJ}/%.o,$(notdir ${SOURCE}))  

#設定最後目标檔案  

 TARGET = main  

 BIN_TARGET = ${BIN}/${TARGET}  

 CC = gcc   

 CFLAGS = -g -Wall -I${INC}   

#用所有中間檔案生成目的檔案,規則中可以用 $^替換掉 ${OBJECT}  

 ${BIN_TARGET}:${OBJECT}  

     $(CC) -o $@ ${OBJECT}  

#生成各個中間檔案  

 ${OBJ}/%.o:${SRC}/%.c   

     $(CC) $(CFLAGS) -o $@ -c $<  

 .PHONY:clean  

 clean:  

     find $(OBJ) -name *.o -exec rm -rf {} \; #這個是find指令,不懂的可以查下資料  

     rm -rf $(BIN_TARGET)  

        這個makefile的好處就是通用性,裡面不涉及到具體的檔案名,當你往src目錄中添加新檔案時,可以不需要修改makefile,是以這是個非常好的工具;

繼續閱讀