首先說說本次嵌套執行makefile文件的目的:只需make根目錄下的makefile文件,即可編譯所有c文件,包括子目錄下的。
意義:自動化編譯行為,以后編譯自己的c文件時可把這些makefile文件直接復制到相應目錄即可方便編譯出所有文件。這些makefile文件是通用的,只需根據自己的工程情況改動少許內容即可。下面會說。
總體思路是:把目標文件放在debug文件夾下的obj目錄下,把最終的二進制文件放在debug文件夾下的bin目錄下;如何遞歸編譯所有除了debug目錄下的makefile文件呢:獲得當前目錄下的所有子目錄,執行子目錄下的makefile文件;獲取當前目錄下的所有c文件,編譯c文件並放到指定的目標文件夾下。最后再執行debug目錄下的makefile文件生成bin文件。
注意:除了debug文件夾比較特殊外,其他的子目錄下都需要有Makefile文件,而且這些Makefile是相同的,除了根目錄下的makefile文件有些不同外。即除了bin和obj目錄以外的其他目錄都需要Makefile文件,即使目錄下沒有c文件或者其他目錄。
過程:首先在根目錄下新建一個debug文件夾,debug文件夾下有bin目錄和obj目錄和一個Makefile文件,結構如下圖。(這個debug文件里的makefile文件需要最后執行)(tree工具需要自己安裝的,ubuntu下直接輸入sudo apt-get install tree即可,但有時可能需要先sudo apt-get update才行)
整個目錄結果如下圖:
然后在根目錄下新建Makefile文件,根目錄下也可能會有c文件,故也需處理根目錄下的c文件,內容如下:
#設置編譯器 CC=gcc #debug文件夾里的makefile文件需要最后執行,所以這里需要執行的子目錄要排除debug文件夾,這里使用awk排除了debug文件夾,讀取剩下的文件夾 SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "debug") print $$9}') #無需下一行的注釋代碼,因為我們已經知道debug里的makefile是最后執行的,所以最后直接去debug目錄下執行指定的makefile文件就行,具體下面有注釋 #DEBUG=$(shell ls -l | grep ^d | awk '{if($$9 == "debug") print $$9}') #記住當前工程的根目錄路徑 ROOT_DIR=$(shell pwd) #最終bin文件的名字,可以更改為自己需要的 BIN=myapp #目標文件所在的目錄 OBJS_DIR=debug/obj #bin文件所在的目錄 BIN_DIR=debug/bin #獲取當前目錄下的c文件集,放在變量CUR_SOURCE中 CUR_SOURCE=${wildcard *.c} #將對應的c文件名轉為o文件后放在下面的CUR_OBJS變量中 CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)} #將以下變量導出到子shell中,本次相當於導出到子目錄下的makefile中 export CC BIN OBJS_DIR BIN_DIR ROOT_DIR #注意這里的順序,需要先執行SUBDIRS最后才能是DEBUG all:$(SUBDIRS) $(CUR_OBJS) DEBUG #遞歸執行子目錄下的makefile文件,這是遞歸執行的關鍵 $(SUBDIRS):ECHO make -C $@ DEBUG:ECHO #直接去debug目錄下執行makefile文件 make -C debug ECHO: @echo $(SUBDIRS) #將c文件編譯為o文件,並放在指定放置目標文件的目錄中即OBJS_DIR $(CUR_OBJS):%.o:%.c $(CC) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/$@ CLEAN: @rm $(OBJS_DIR)/*.o @rm -rf $(BIN_DIR)/*
上面的注釋很詳細了,具體的命令如果不清楚,自己可以google一下,譬如:wildcard patsubst awk等
讀者可以根據自己的需要更改自己的debug目錄和目標文件目錄和bin文件目錄
其他子目錄下的Makefile文件的內容如下:
1 #子目錄的Makefile直接讀取其子目錄就行 2 SUBDIRS=$(shell ls -l | grep ^d | awk '{print $$9}') 3 #以下同根目錄下的makefile的相同代碼的解釋 4 CUR_SOURCE=${wildcard *.c} 5 CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)} 6 all:$(SUBDIRS) $(CUR_OBJS) 7 $(SUBDIRS):ECHO 8 make -C $@ 9 $(CUR_OBJS):%.o:%.c 10 $(CC) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/$@ 11 ECHO: 12 @echo $(SUBDIRS)
debug目錄下的Makefile文件如下:
1 OBJS=*.o 2 ODIR=obj 3 $(ROOT_DIR)/$(BIN_DIR)/$(BIN):$(ODIR)/$(OBJS) 4 $(CC) -o $@ $^
最后只需在根目錄下,我的是我的根目錄makefile目錄下,執行make命令即可:
結果目錄結果為:
然后執行". debug/bin/myapp"即可;最后可以執行make CLEAN清楚掉所有的目標文件和bin文件。
參考資料為:http://blog.csdn.net/zplove003/article/details/7066595
關於makefile文件的編寫,見一下鏈接:跟我一起寫makefile和http://wiki.ubuntu.org.cn/index.php?title=%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile&variant=zh-cn