首先說說本次嵌套執行makefile文件的目的:只需make根目錄下的makefile文件,便可編譯全部c文件,包括子目錄下的。php
意義:自動化編譯行爲,之後編譯本身的c文件時可把這些makefile文件直接複製到相應目錄便可方便編譯出全部文件。這些makefile文件是通用的,只需根據本身的工程狀況改動少量內容便可。下面會說。shell
整體思路是:把目標文件放在debug文件夾下的obj目錄下,把最終的二進制文件放在debug文件夾下的bin目錄下;如何遞歸編譯全部除了debug目錄下的makefile文件呢:得到當前目錄下的全部子目錄,執行子目錄下的makefile文件;獲取當前目錄下的全部c文件,編譯c文件並放到指定的目標文件夾下。最後再執行debug目錄下的makefile文件生成bin文件。ubuntu
注意:除了debug文件夾比較特殊外,其餘的子目錄下都須要有Makefile文件,並且這些Makefile是相同的,除了根目錄下的makefile文件有些不一樣外。即除了bin和obj目錄之外的其餘目錄都須要Makefile文件,即便目錄下沒有c文件或者其餘目錄。app
過程:首先在根目錄下新建一個debug文件夾,debug文件夾下有bin目錄和obj目錄和一個Makefile文件,結構以下圖。(這個debug文件裏的makefile文件須要最後執行)(tree工具須要本身安裝的,ubuntu下直接輸入sudo apt-get install tree便可,但有時可能須要先sudo apt-get update才行)工具
整個目錄結果以下圖:google
而後在根目錄下新建Makefile文件,根目錄下也可能會有c文件,故也需處理根目錄下的c文件,內容以下:spa
#設置編譯器 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等.net
讀者能夠根據本身的須要更改本身的debug目錄和目標文件目錄和bin文件目錄
debug
其餘子目錄下的Makefile文件的內容以下:code
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