多文件目錄下makefile文件遞歸執行編譯所有c文件


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM