標籤:
首先說說本次嵌套執行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最後才能是DEBUGall:$(SUBDIRS) $(CUR_OBJS) DEBUG#遞迴執行子目錄下的makefile檔案,這是遞迴執行的關鍵$(SUBDIRS):ECHO make -C [email protected]DEBUG:ECHO #直接去debug目錄下執行makefile檔案 make -C debugECHO: @echo $(SUBDIRS)#將c檔案編譯為o檔案,並放在指定放置目標檔案的目錄中即OBJS_DIR$(CUR_OBJS):%.o:%.c $(CC) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/[email protected]CLEAN: @rm $(OBJS_DIR)/*.o @rm -rf $(BIN_DIR)/*
上面的注釋很詳細了,具體的命令如果不清楚,自己可以google一下,譬如:wildcard patsubst awk等
讀者可以根據自己的需要更改自己的debug目錄和目標檔案目錄和bin檔案目錄
其他子目錄下的Makefile檔案的內容如下:
#子目錄的Makefile直接讀取其子目錄就行SUBDIRS=$(shell ls -l | grep ^d | awk ‘{print $$9}‘)#以下同根目錄下的makefile的相同代碼的解釋CUR_SOURCE=${wildcard *.c}CUR_OBJS=${patsubst %.c, %.o, $(CUR_SOURCE)}all:$(SUBDIRS) $(CUR_OBJS)$(SUBDIRS):ECHO make -C [email protected]$(CUR_OBJS):%.o:%.c $(CC) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/[email protected]ECHO: @echo $(SUBDIRS)
debug目錄下的Makefile檔案如下:
OBJS=*.oODIR=obj$(ROOT_DIR)/$(BIN_DIR)/$(BIN):$(ODIR)/$(OBJS) $(CC) -o [email protected] $^
最後只需在根目錄下,我的是我的根目錄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
【轉】多檔案目錄下makefile檔案遞迴執行編譯所有c檔案