今天看了一天的makefile的寫法,東拼西湊,好不容易寫出了一個makefile,很有成就感,記錄下來,以備溫習之用。shell
假設有兩個頭文件目錄 header1,header2;兩個cpp文件目錄,src1,src2,一個lib目錄函數
寫一個完整的makefile步驟以下:spa
1 定義可執行文件的名稱字符串
TARGET = MyPro 編譯器
2 指定此編譯工程所要使用的頭文件所在的目錄編譯
INC = -I. -Iheader1 -Iheader2變量
3 指定cpp文件所在的目錄object
VPATH = .:src1:src2foreach
4 指定全部的cpp文件file
SRC_PATH = $(foreach dir,$(subst :, ,$(VPATH)),$(wildcard $(dir)/,*.cpp))
解釋:
foreach,subst,wildcard爲makefile的內置函數,其中wildcard函數爲字符串鏈接函數,把函數中的兩個參數鏈接成一個。subst是字符串替換函數,在此句中意思是把VPATH變量中的冒號替換成空格。foreach函數,就是把subst函數的返回值,以空格爲分隔符,循環取值賦給dir,而後接受wildcard的處理。
這句的整體意思是:從VPATH中獲取每一個目錄,並分別找出此目錄下全部的cpp文件,賦給SRC_PATH變量。
5 定義中間object文件存放的目錄。
OBJ_DIR = ./obj
6 全部的object文件要按照和源代碼對應的目錄存放,定義object文件的目錄
OBJ_PATH = $(addprefix $(OBJ_DIR)/, $(subst :, ,$(VPATH) ) )
解釋:
addprefix函數是加前綴的函數,詞句中是給VPATH中全部已經定義的目錄加上./obj/的前綴。
7 定義鏈接成目標文件所須要的全部的object文件的名稱
OBJS = $(addprefix $(OBJ_DIR),$(subst .cpp,.o,$(SRC_PATH)))
8 建立一個object文件的目錄
MAKE_OBJECT_DIR := $(shell mkdir -p $(OBJ_DIR) $(OBJ_PATH))
*************************
9 定義實用的編譯器
CXX = g++
CXXFLAGS = -g
10 定義目標文件的生成規則
$(TARGET) : $(OBJS)
$(CXX) -o $@ $(OBJS) $(INC) $(CXXFLAGS)
11 定義object文件的生成方式:
$(OBJ_DIR)/%.o : %.cpp %.cpp.d
$(CXX) -o $@ -c $< $(INC) $(CXXFLAGS)
12 定義.cpp.d文件的生成方式
DEPS = $(OBJS:.o=.cpp.d)
$(DEPS) : $(OBJ_DIR)/%.cpp.d : %.cpp
$(CXX) $< -MM $(INC) > $(OBJ_DIR)/$<.d
13 定義清理函數
clean:
@rm -rf ./obj
@rm -rf $(TARGET)
至此,一個通用的makefile完成了,若是增長源代碼目錄和頭文件目錄,只須要在INC變量和VPATH變量處加上此目錄便可。中間object文件和文件的依賴關係自動生成。