多文件目錄下makefile文件遞歸執行編譯全部c文件

首先說說本次嵌套執行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

相關文章
相關標籤/搜索