makefile
模板 1
# 一個適合中小規模的makefile模版,基本上自己按照實際情況指定一下 原始檔,目標檔案,標頭檔案目錄,以及原始檔字尾就行了。
# ---------------------------------------------------------------------------
# commands
# ---------------------------------------------------------------------------
CC := gcc
LINK := gcc
RM := rm -rf
MV := mv
TAR := tar
MKDIR := mkdir
# ---------------------------------------------------------------------------
# settings
# ---------------------------------------------------------------------------
SRC_SUFFIX := .c
OBJ_SUFFIX := .o
LIB_SUFFIX := .a
BIN_SUFFIX := .exe
DLL_SUFFIX := .so
INC_PREFIX := -I
LIB_PREFIX := -L
OPT_C := -c
OPT_OUT := -o
OPT_LINKOUT := -o
CFLAGS := $(OPT_C)
LIBFLAGS := -Debug
# ---------------------------------------------------------------------------
# directories
# ---------------------------------------------------------------------------
SRC_DIR := ./src
OBJ_DIR := ./obj
INC_DIR := ./inc
LIB_DIR := ./lib /usr/local/lib /lib /usr/lib
# ---------------------------------------------------------------------------
# common settings
# ---------------------------------------------------------------------------
SRCS := $(wildcard $(SRC_DIR)/*$(SRC_SUFFIX))
OBJS := $(patsubst $(SRC_DIR)/%$(SRC_SUFFIX),$(OBJ_DIR)/%$(OBJ_SUFFIX),$(SRCS))
INCS := $(addprefix $(INC_PREFIX), $(INC_DIR))
LIBS := $(addprefix $(LIB_PREFIX), $(LIB_DIR)) $(LIBFLAGS)
TEMPFILES := core core.* *$(OBJ_SUFFIX) temp.* *.out typescript*
# ---------------------------------------------------------------------------
# make rule
# ---------------------------------------------------------------------------
TARGET := loader
.PHONY: all clean
all: $(TARGET)
clean:
$(RM) $(TARGET)$(BIN_SUFFIX) $(OBJS)
$(TARGET):$(OBJS)
$(LINK) $(OPT_LINKOUT)$(TARGET)$(BIN_SUFFIX) $(LIBS) $(OBJS)
$(OBJS):$(OBJ_DIR)/%$(OBJ_SUFFIX):$(SRC_DIR)/%$(SRC_SUFFIX)
$(CC) $(CFLAGS) $(INCS) $(OPT_OUT)$@ $<
模板 2
CXX := g++
SRC_DIR := ./src
OBJ_DIR := ./build
BIN_DIR := ./bin
INC_DIR := ./include
VPATH = $(INC_DIR) $(OBJ_DIR) $(SRC_DIR)
vpath %.h $(INC_DIR)
# 一種搜尋原始檔的方式
# SRC_DIRS = $(shell find $(SRC_DIR) -maxdepth 3 -type d)
# SRCS = $(foreach dir, $(SRC_DIRS), $(wildcard $(dir)/*.cpp))
# TODO: 這樣子出來的目標檔案,在jing'tai時就找不到依賴了
# OBJS := $(OBJ_DIR)/$(notdir $(patsubst %.cpp, %.o, $(SRCS)))
SRCS := $(wildcard $(SRC_DIR)/*.cpp)
OBJS := $(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(SRCS))
INCS := $(addprefix -I, $(INC_DIR))
BUILDING_DIRS := $(OBJ_DIR) $(BIN_DIR)
TARGET := adb_lab2.exe
RUN := run.sh
$(TARGET) : $(BUILDING_DIRS) $(OBJS)
$(CXX) -o $(BIN_DIR)/$(TARGET) $(OBJS)
@touch $(RUN)
@echo "$(BIN_DIR)/$(TARGET)" > $(RUN)
# 這裡的字首不能少。makefile不會自動去VPATH裡面找這幾個目標,而是直接當成新的目標來對待
$(OBJ_DIR)/BufferPoolManager.o : BufferPoolManager.h LRUReplacer.h
$(OBJ_DIR)/DataStorageManager.o : DataStorageManager.h
$(OBJ_DIR)/LRUReplacer.o : LRUReplacer.h
$(OBJ_DIR)/main.o : BufferPoolManager.h
# 一個建立執行時依賴資料夾的方法
$(BUILDING_DIRS) :
@mkdir $@
# 這叫 靜態模式
$(OBJS) : $(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp
$(CXX) -o $@ -c $< $(INCS)
.PHONY: all clean output
all : $(TARGET)
clean:
-rm -rf $(BUILDING_DIRS) test.dbf $(RUN)
output:
@echo $(SRCS)
@echo --------------
@echo $(OBJS)
模板 3
CC := gcc
CC_INCLUDE_FLAGS := -I ./include/
CC_FLAGS := $(CC_INCLUDE_FLAGS) -g
# 程式執行的引數
ARGS := ~/codes
DIR_SRC := ./src
DIR_OBJ := ./build
DIR_EXE := ./bin
SRCS := $(shell find $(DIR_SRC) -name "*.c")
OBJS := $(patsubst $(DIR_SRC)/%.c, $(DIR_OBJ)/%.o, $(SRCS))
DPTS := $(patsubst %.c, %.d, $(SRCS))
DIRS := $(DIR_OBJ) $(DIR_EXE)
target := $(DIR_EXE)/my_ls_pro
$(target): $(DIRS) $(OBJS)
$(CC) $(OBJS) -o $@
$(DIRS):
@mkdir $@
$(DIR_OBJ)/%.o: $(DIR_SRC)/%.c
$(CC) $(CC_FLAGS) -c $< -o $@
%.d: %.c
@set -e; \
rm -f $@; \
$(CC) -MM $(CC_FLAGS) $< $(CC_INCLUDE_FLAGS) > $@.$$$$.dtmp; \
sed 's,\(.*\)\.o\:,$*\.o $*\.d\:,g' < $@.$$$$.dtmp > $@;\
rm -f $@.$$$$.dtmp
-include $(DPTS)
clean:
rm -f $(OBJS)
rm -f $(DPTS)
run:
make
$(target) $(ARGS)
教程
REF1:makefile 簡明教程, REF2:如何輸出到指定資料夾 ,REF3:關於自動生成依賴.d 檔案
模式替換
$(patsubst <pattern>,<replacement>,<text> )
查詢
這裡,
$(patsubst %.c,%.o, a.c b.c)
# 把字串 “a.c b.c” 符合模式[%.c]的單詞替換成[%.o],返回結果是 “a.o b.o”
變數替換引用
對於一個已經定義的變數,可以使用“替換引用”將其值中的字尾字元(串)使用指定的字元(字串)替換。格式為$(VAR:A=B)
或者${VAR:A=B}
意思是,替換變數“VAR”中所有“A”字元結尾的字為“B”結尾的字。“結尾”的含義是空格之前(變數值多個字之間使用空格分開)。而對於變數其它部分的“A”字元不進行替換。
foo := a.o b.o c.o
bar := $(foo:.o=.c)
# 注意變數不要帶 $
SRCS_NODIR := $(notdir $(wildcard $(SRC_DIR)/*$(SRC_SUFFIX)))
OBJS_NODIR := $(SRCS_NODIR:$(SRC_SUFFIX)=$(OBJ_SUFFIX))