這是我app目錄下的文件夾結構,每個目錄比如debug,debug/bin,debug/obj等都需要自己手動創建,並且最好給予足夠的rwx權限,這里Makefile沒有自動創建目錄。
. |-- Makefile |-- debug | |-- Makefile | |-- bin | | `-- app | `-- obj | |-- main.o | `-- test_file_stat.o |-- main.c |-- test | |-- Makefile | |-- test_file_stat.c | `-- test_file_stat.h `-- text.txt
1.下面是根目錄app目錄下的Makefile文件:
#設置編譯器
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=app
#目標文件所在的目錄
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
#make-successful...
#遞歸執行子目錄下的makefile文件,這是遞歸執行的關鍵
$(SUBDIRS):ECHO
make -C $@
DEBUG:ECHO
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)/*
2.下面是子目錄test測試目錄的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 $@
$(CUR_OBJS):%.o:%.c
$(CC) -c $^ -o $(ROOT_DIR)/$(OBJS_DIR)/$@
ECHO:
@echo $(SUBDIRS)
3.下面是目標debug目錄下的Makefile文件:
OBJS=*.o
ODIR=obj
$(ROOT_DIR)/$(BIN_DIR)/$(BIN):$(ODIR)/$(OBJS)
$(CC) -o $@ $^
4.寫好后,只要在app目錄下執行 make ,即可在debug/bin目錄下生成可執行文件app了。
5.執行 ./debug/bin/app即可運行可執行文件app了。