Makefile通用模板
一、适用于各种项目,统一管理编译中间文件的模板:
#############################################################################
# User Define
#############################################################################
# compiler output file storage directory
BIN_DIR = ../Bin
# setting the compilation target type: exec file, shared library, static library
EXE_NAME = test
LIB_NAME =
SLIB_NAME =
# setting tools flags
CFLAGS += -Wall
CXXFLAGS += -Wall
LDFLAGS += -Wall
ARFLAGS +=
#-crus -rcs
# include head files directory
INC_DIRS = ./ \
./ThirdParty/inc
# include all source files
SRC_FILES = ./*.c \
./src/*.c
# include library directory
LIB_DIRS = ./ThirdParty/lib
# used librarys
USED_LIBS = ThirdPartySdk
#############################################################################
# Common Define
#############################################################################
# set tools
CC = gcc
CXX = g++
AR = ar
LD = ld
# some defaults
ifndef CFG
CFG = Release
endif
# find out the platform on which we're running
MACHINE = $(shell uname -m)
ifneq (,$(findstring x86_64,$(MACHINE)))
HOST_PLATFORM = x64
else ifneq (,$(findstring x86,$(MACHINE)))
HOST_PLATFORM = x86
else ifneq (,$(findstring i686,$(MACHINE)))
HOST_PLATFORM = x86
else ifneq (,$(findstring i386,$(MACHINE)))
HOST_PLATFORM = x86
else ifneq (,$(findstring arm,$(MACHINE)))
HOST_PLATFORM = arm
else ifneq (,$(findstring aarch64,$(MACHINE)))
HOST_PLATFORM = aarch64
else
DUMMY:=$(error Can't determine host platform)
endif
ifeq "$(PLATFORM)" ""
PLATFORM = $(HOST_PLATFORM)
endif
# expand file list
SRC_FILES_LIST = $(wildcard $(SRC_FILES))
# define the intermediate directory
INT_DIR = $(BIN_DIR)/Intermediate/$(PLATFORM)-$(CFG)/$(OUTPUT_NAME)
# define output directory
OUT_DIR = $(BIN_DIR)/$(PLATFORM)-$(CFG)
# full path to output file
OUTPUT_FILE = $(OUT_DIR)/$(OUTPUT_NAME)
# define a function to figure .o file for each source file (placed under intermediate directory)
SRC_TO_OBJ = $(addprefix ./$(INT_DIR)/,$(addsuffix .o,$(notdir $(basename $1))))
# create a list of all object files
OBJ_FILES = $(call SRC_TO_OBJ,$(SRC_FILES_LIST))
# append the -I switch to each include directory
INC_DIRS_OPTION = $(foreach dir,$(INC_DIRS),-I$(dir))
# append the -L switch to each library directory
LIB_DIRS_OPTION = $(foreach dir,$(LIB_DIRS),-L$(dir)) -L$(OUT_DIR)
# append the -l switch to each library used
USED_LIBS_OPTION = $(foreach lib,$(USED_LIBS),-l$(lib))
# set Debug / Release flags
ifeq "$(CFG)" "Debug"
CFLAGS += -O0 -g
endif
ifeq "$(CFG)" "Release"
CFLAGS += -O2 -DNDEBUG
endif
CFLAGS += $(INC_DIRS_OPTION)
CFLAGS += -fPIC -fvisibility=hidden
ifneq "$(ALLOW_WARNINGS)" "1"
CFLAGS += -Werror
endif
LDFLAGS += $(LIB_DIRS_OPTION) $(USED_LIBS_OPTION)
# some lib / exe specifics
ifneq "$(EXE_NAME)" ""
OUTPUT_NAME = $(EXE_NAME)
# We want the executables to look for the .so's locally first:
LDFLAGS += -Wl,-rpath ./
OUTPUT_COMMAND = $(CC) -o $(OUTPUT_FILE) $(OBJ_FILES) $(LDFLAGS)
endif
ifneq "$(LIB_NAME)" ""
OUTPUT_NAME = lib$(LIB_NAME).so
LDFLAGS += -Wl,--no-undefined
OUTPUT_COMMAND = $(CC) -o $(OUTPUT_FILE) $(OBJ_FILES) $(LDFLAGS) -shared
endif
ifneq "$(SLIB_NAME)" ""
OUTPUT_NAME = lib$(SLIB_NAME).a
OUTPUT_COMMAND = $(AR) $(ARFLAGS) $(OUTPUT_FILE) $(OBJ_FILES)
# OUTPUT_COMMAND = $(AR) -cq $(OUTPUT_FILE) $(OBJ_FILES)
endif
define CREATE_SRC_TARGETS
$(call SRC_TO_OBJ,$1) : $1 | $(INT_DIR)
$(CC) -c $(CFLAGS) -o $$@ $$<
endef
# $(CC) -M -c $(CFLAGS) -o $$@ $$<
#############################################################################
# Targets
#############################################################################
# Specify suffix names and pseudo-targets
.SUFFIXES: .c,.o,.cpp,.S,.s
.PHONY: all clean distclean
# define the target 'all' (it is first, and so, default)
all: $(OUTPUT_FILE) $(OUT_DIR)
# Intermediate directory
$(INT_DIR):
mkdir -p $(INT_DIR)
# Output directory
$(OUT_DIR):
mkdir -p $(OUT_DIR)
# Final output file
$(OUTPUT_FILE): $(SRC_FILES_LIST) | $(OUT_DIR)
# create targets for each source file
$(foreach src,$(SRC_FILES_LIST),$(eval $(call CREATE_SRC_TARGETS,$(src))))
# Final targets
$(OUTPUT_FILE): $(OBJ_FILES)
$(OUTPUT_COMMAND)
clean:
rm -rf $(OBJ_FILES)
rm -rf $(OUTPUT_FILE)
distclean:
rm -rf $(BIN_DIR)
二、Makefile模板基础
#Makefile规则:
#TARGET … : DEPENDENCIES …
# COMMAND
# …
#定义变量,下面一句表示指定头文件所在的位置加载头文件,-l头文件包名
CPPFLAGS = -Wall -O2
CFLAGS =
LDFLAGS= -lpthread
CC=g++
TARGET = Demo
#$(wildcard *.c)表示当前目录下的所有.c文件
src = $(wildcard *.cpp)
#下面的意思是将所有的.c文件替换成为.o文件
obj=$(patsubst %.cpp,%.o,$(src))
## 利用makefile可以编译多个可执行文件
## 模式规则
#%.o:%.cpp
## 后缀规则
#.cpp.o:
#程序最终编译成app,依赖$(obj),而需要执行的命令是紧接着的下面一句,$^表示所有的依赖,
# $@表示要生成的目标,这句的目标是$(target),也就是app文件
$(TARGET):$(obj)
$(CC) $^ $(LDFLAGS) -o $@
#$<表示一个的编译成目标文件$@
%.o: %.cpp
$(CC) -c $< $(CFLAGS) $(CPPFLAGS) -o $@
#通过这种方式避免和当前已存在的clean文件冲突,下面声明的是一个伪目标
.PHONY: clean
#彻底清除生成过程文件
clean:
-rm -f *.o
-rm -f $(TARGET)
#彻底清除过程文件和生成配置文件
distclean:
rm /usr/bin/app
install:
cp app /usr/bin