makefile專題:路徑搜索的綜合示例

1. 需求分析

1)工程項目中不希望源碼文件夾在編譯時被改動(只讀文件夾)
2)在編譯時自動創(chuàng)建文件夾(build)用于存放編譯結(jié)果
3)編譯過程中能夠自動搜索需要的文件
4)makefile易于擴展,能夠復(fù)用相同類型的項目
5)支持調(diào)試版本的編譯選項

2. 項目類型分析

3. 工具原料

  • $(wildcard $(DIR)/_pattern):獲取$(DIR)文件夾中滿足_pattern的文件
  • $(notdir _names):去除_names中每一個文件名的路徑前綴
  • $(patsubst _pattern, replacement, _text):將_text中符合_pattern的部分替換為replacement

4. 關(guān)鍵技巧

1)自動獲取源文件列表(函數(shù)調(diào)用):SRCS := $(wildcard src/*.c)
2)根據(jù)源文件列表生成目標文件列表(變量的值替換):OBJS := $(SRCS:.c=.o)
3)替換每一個目標文件的路徑前綴(函數(shù)調(diào)用):OBJS := $(patsubst src/%, build/%, $(OBJS))

5. 編譯規(guī)則的依賴

.PHONY : all clean

DIR_BUILD := build
DIR_SRC := src
DIR_INC := inc

CC := gcc

CFLAGS := -I $(DIR_INC)

MKDIR := mkdir
RM := rm -rf

APP := $(DIR_BUILD)/app.out
HDRS := $(wildcard $(DIR_INC)/*.h)
HDRS := $(notdir $(HDRS))
OBJS := $(wildcard $(DIR_SRC)/*.c)
OBJS := $(OBJS:.c=.o)
OBJS := $(patsubst $(DIR_SRC)/%, $(DIR_BUILD)/%, $(OBJS))

vpath %.h $(DIR_INC)
vpath %.c $(DIR_SRC)

all : $(DIR_BUILD) $(APP)
    @echo "Target File ==> $(APP)"

$(DIR_BUILD) : 
    $(MKDIR) $@

$(APP) : $(OBJS)
    $(CC) -o $@ $^

$(DIR_BUILD)/%.o : %.c $(HDRS)
    $(CC) $(CFLAGS) -o $@ -c $<

clean:
    $(RM) $(DIR_BUILD)

提高擴展性,修改后:

.PHONY : all clean

DIR_BUILD := build
DIR_SRC := src
DIR_INC := inc

# 用變量表示后綴類型
TYPE_INC := .h
TYPE_SRC := .c
TYPE_OBJ := .o

CC := gcc
# 添加鏈接標簽
LFLAGS :=
CFLAGS := -I $(DIR_INC)
# 添加DEBUG版本
ifeq ($(DEBUG), true)
CFLAGS += -g
endif

MKDIR := mkdir
RM := rm -rf

APP := $(DIR_BUILD)/app.out
HDRS := $(wildcard $(DIR_INC)/*$(TYPE_INC))
HDRS := $(notdir $(HDRS))
OBJS := $(wildcard $(DIR_SRC)/*$(TYPE_SRC))
OBJS := $(OBJS:$(TYPE_SRC)=$(TYPE_OBJ))
OBJS := $(patsubst $(DIR_SRC)/%, $(DIR_BUILD)/%, $(OBJS))

vpath %$(TYPE_INC) $(DIR_INC)
vpath %$(TYPE_SRC) $(DIR_SRC)

all : $(DIR_BUILD) $(APP)
    @echo "Target File ==> $(APP)"

$(DIR_BUILD) : 
    $(MKDIR) $@

$(APP) : $(OBJS)
    $(CC) $(LFLAGS) -o $@ $^

$(DIR_BUILD)/%$(TYPE_OBJ) : %$(TYPE_SRC) $(HDRS)
    $(CC) $(CFLAGS) -o $@ -c $<

clean:
    $(RM) $(DIR_BUILD)

6. 小結(jié)

  • 工程項目中不希望源碼文件夾在編譯時被改動
  • 模式規(guī)則的靈活運用使得makefile具有復(fù)用性
  • 變量的靈活運用使得makefile具有擴展性
  • 規(guī)模較小的項目沒有必要使用自動生成依賴關(guān)系的解決方案
  • 規(guī)模較小的項目可以直接讓源文件依賴于頭文件(易于維護)

聲明:此文章為本人在學習狄泰軟件學院《十二月提升計劃》所做的筆記,參考書籍《專業(yè)嵌入式軟件開發(fā)》——李云,文章中包含狄泰軟件資料內(nèi)容和《專業(yè)嵌入式軟件開發(fā)》資料內(nèi)容,一切版權(quán)歸狄泰軟件《專業(yè)嵌入式軟件開發(fā)》所有!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 實戰(zhàn)需求 1)自動生成target文件夾存放可執(zhí)行文件2)自動生成objs文件夾存放編譯生成的目標文件(* ...
    編程半島閱讀 280評論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,648評論 19 139
  • 姓名~夏斐 -利他組 【日精進打卡第2天】 【知~學習】 《六項精進》1遍 共2遍 《大學》2遍 共3遍 ????...
    斐然之夏閱讀 295評論 0 0

友情鏈接更多精彩內(nèi)容