這是我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了。