路徑搜索的綜合示例(十三)
我們來看看這種項目的類型,如下
那麽我們需要的工具原料有:a> $(wildcard $(DIR)/_pattern),用來獲取 $(DIR) 文件夾中滿足 _pattern 的文件;b> $(notdir _names)
下來我們來看看 makefile 怎麽寫,src 和 inc 文件夾還是之前的
.PHONY : all clean rebuild DIR_BUILD := build DIR_SRC := src DIR_INC := inc TYPE_INC := .h TYPE_SRC := .c TYPE_OBJ := .o CC := gcc CFLAGS := -I $(DIR_INC) 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) -o $@ $^ $(DIR_BUILD)/%$(TYPE_OBJ) : %$(TYPE_SRC) $(HDRS) $(CC) $(CFLAGS) -o $@ -c $< clean : $(RM) $(DIR_BUILD) rebuild : $(MAKE) clean $(MAKE) all
我們看到變量 HDRS 是先進入到 inc 文件夾下獲取到所需的 .h 頭文件,然後再經過 notdir 去除掉它的路徑名。我們利用 TYPE_XXX 來定義相應的 頭文件(或源文件或目標文件),這樣做是為了讓這個 makefile 具有更好的移植性。利用 vpath 來指定相應的路徑。通過 DEBUG 宏判斷它是否為調試版本。下來我們先來看看它是否能正常工作。
我們看到它已經正確工作了,並且在 build 文件夾下生產相應的 app.out 以及 .o 文件,原 inc 和 src 文件夾並沒有被汙染。這便達到了我們的要求了,如果是換一個類似的項目(包含有 .h 的頭文件庫和 .c 的源文件庫),我們也能直接拿去這個 makefile 進行使用;如果是 C++ 項目,那麽我們換個 g++ 編譯器就可以正常工作。但是有個小問題,就是如果其中有一個頭文件改動,整個項目就必須全部編譯。我們就得思考了:對於規則較小的項目,我們在 makefile 中是否也需要使用自動生成依賴關系的解決方案呢?如果使用自動生成依賴關系的解決方案,那麽整個的 makefile 代碼的編寫就相當復雜了。我們究竟該如何做呢?如果對於較小的項目,我們就不必使用自動生成依賴關系,因為此時不但是 makefile 的編寫比較復雜,而且不利用後期的維護。
通過對路徑搜索的綜合開發的學習,總結如下:1、工程項目中不希望源碼文件夾在編譯時被改動,模式規則的靈活運用使得 makefile 具有復用性;2、變量的靈活運用使得 makefile 具有擴展性;3、規模較小的項目沒必要使用自動生成依賴關系的解決方案;4、規則較小的項目可以直接讓源文件依賴於頭文件(原因就是易於維護)。
歡迎大家一起來學習 makefile 語言,可以加我QQ:243343083。
路徑搜索的綜合示例(十三)