天天看點

使用Makefile編譯多個c源代碼的方法

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

繼續閱讀