##################################################
################ 可修改和配置参数 ################
##################################################
#目标文件名,例如:test, 为动态库时文件名=libtest.so,为静态库时文件名=libtest.a
TARGET := test
#目标类型,选项值:app - 应用程序, shared - 动态库, static - 静态库
TYPE := app
#标识定义,例如:ARM 或 x86
DEFINES :=
#源码宏定义,例如:-DDEBUG -DTEST=1
MACROS :=
#指定安装路径(默认安装到当前路径)
SET_PATH :=
#头文件路径(添加当前路径为搜索路径:-I.),例如:-I/user/include
INC_PATH := -I.
#源文件路径(默认从当前路径搜索)
SRC_PATH := algorithm \
common \
formula \
httpserver \
inifile \
logfile \
probability \
process \
pugixml \
shareprefs \
xmlhelper
#静态库文件(默认从当前路径搜索),例如:libgendll.a
LIB_STATICS := libevent/libevent.a libevent/libevent_core.a libevent/libevent_extra.a libevent/libevent_pthreads.a
ifeq (ARM,$(filter ARM,$(DEFINES)))
LIB_STATICS += jpeg/lib/arm/libjpeg.a
else
LIB_STATICS += jpeg/lib/x86/libjpeg.a
endif
#指定运行时动态库搜索路径
ifeq (ARM,$(filter ARM,$(DEFINES)))
RPATH := 3rd/openssl/lib/arm:3rd/mosquitto/lib/arm
else
RPATH := 3rd/openssl/lib/x64:3rd/mosquitto/lib/x64
endif
#动态库路径(添加当前路径为搜索路径:-L.),例如:-L/user/lib
LDFLAGS := -L.
ifeq (ARM,$(filter ARM,$(DEFINES)))
LDFLAGS += -L3rd/openssl/lib/arm -L3rd/mosquitto/lib/arm
else
LDFLAGS += -L3rd/openssl/lib/x64 -L3rd/mosquitto/lib/x64
endif
#动态库文件,例如:-lpthread
LIBS := -lpthread -lcrypto -lssl -lmosquitto
#编译器,这里针对不同目标平台做选择
CC := g++
AR := ar
ifeq (ARM,$(filter ARM,$(DEFINES)))
CC := /opt/poky/1.7/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-g++ -march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a7
AR := /opt/poky/1.7/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-ar
endif
#C编译器选项
CFLAGS := -g -Wall -O3 -Wl,-rpath=$(RPATH)
#C++编译器选项
CXXFLAGS := -DHAVE_CONFIG_H -std=c++11
#构建目录,存放临时文件
BUILD_DIR ?= _build
OBJ_C_DIR ?= $(BUILD_DIR)/object_c
OBJ_CXX_DIR ?= $(BUILD_DIR)/object_cxx
######################################################################
#Brief: 搜索当前目录下的子节点(包含目录和文件)
#Param: 空
#Return: 列表,空格分隔
######################################################################
define pwdFiles
$(1) = $(wildcard *)
endef
######################################################################
#Brief: 搜索指定目录下的子节点(包含目录和文件)
#Param: 参数1 - 目录列表,空格分隔,如.a b c
#Return: 列表,空格分隔
######################################################################
define searchFiles
$(1) = $(foreach dir,$(1),$(wildcard $(dir)/*))
endef
######################################################################
####################### 构建流程,基本不需再修改 ######################
######################################################################
#当前路径
CURPATH := $(shell dirname $(shell pwd)/$(lastword $(MAKEFILE_LIST)))/
ifeq (,$(SET_PATH))
SET_PATH := $(CURPATH)
endif
#源文件
SOURCES := $(filter %.c %.cc %.cpp %.hpp,$(call pwdFiles) $(call searchFiles,$(SRC_PATH)))
#.d文件(依赖关系)
DEPENDS_C := $(patsubst %.c,$(OBJ_C_DIR)/%.d,$(filter %.c,$(SOURCES)))
DEPENDS_CC := $(patsubst %.cc,$(OBJ_CXX_DIR)/%.d,$(filter %.cc,$(SOURCES)))
DEPENDS_CPP := $(patsubst %.cpp,$(OBJ_CXX_DIR)/%.d,$(filter %.cpp,$(SOURCES)))
DEPENDS_HPP := $(patsubst %.hpp,$(OBJ_CXX_DIR)/%.d,$(filter %.hpp,$(SOURCES)))
DEPENDS := $(DEPENDS_C) $(DEPENDS_CC) $(DEPENDS_CPP) $(DEPENDS_HPP)
#.o文件
OBJECTS := $(DEPENDS:%.d=%.o)
#编译参数
FLAGS := $(MACROS) $(INC_PATH) $(CFLAGS) $(CXXFLAGS)
ifeq (shared,$(TYPE)) # 动态库
FLAGS += -fpic -shared
TARGET := lib$(TARGET).so
endif
ifeq (static,$(TYPE)) # 静态库
TARGET := lib$(TARGET).a
endif
#链接库参数(静态库在前,动态库在后)
LIB_FLAGS := $(LIB_STATICS) $(LDFLAGS) $(LIBS)
#伪目标
.PHONY: help
#帮助说明
help:
@echo "Build Help for Target '$(TARGET)':"
@echo " make all -- build project, aborted after an error"
@echo " make clean -- delete files [.d .o] in folder '$(BUILD_DIR)'"
@echo " make veryclean -- delete folder '$(BUILD_DIR)'"
@echo " make rebuild -- rebuild project"
@echo " make install -- install to the path '$(SET_PATH)'"
#编译构建
all: $(TARGET)
#编译c源码的.d文件
$(OBJ_C_DIR)/%.d: %.c
@mkdir -p $(@D)
@set -e; rm -f $@; \
$(CC) -MM $(FLAGS) $< > $@.$$$$; \
sed 's,$(notdir $*)\.o[ :]*,$(OBJ_C_DIR)/$*\.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
#编译c++源码的.d文件
$(OBJ_CXX_DIR)/%.d: %.cc
@mkdir -p $(@D)
@set -e; rm -f $@; \
$(CC) -MM $(FLAGS) $< > $@.$$$$; \
sed 's,$(notdir $*)\.o[ :]*,$(OBJ_CXX_DIR)/$*\.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
$(OBJ_CXX_DIR)/%.d: %.cpp
@mkdir -p $(@D)
@set -e; rm -f $@; \
$(CC) -MM $(FLAGS) $< > $@.$$$$; \
sed 's,$(notdir $*)\.o[ :]*,$(OBJ_CXX_DIR)/$*\.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
$(OBJ_CXX_DIR)/%.d: %.hpp
@mkdir -p $(@D)
@set -e; rm -f $@; \
$(CC) -MM $(FLAGS) $< > $@.$$$$; \
sed 's,$(notdir $*)\.o[ :]*,$(OBJ_CXX_DIR)/$*\.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
#编译.o文件描述
o_describe:
@echo "========================== Generate .o File =========================="
#编译c源码的.o文件
$(OBJ_C_DIR)/%.o: %.c
@echo $@
@mkdir -p $(@D)
@$(CC) $(FLAGS) -c $< -o $@
#编译c++源码的.o文件
$(OBJ_CXX_DIR)/%.o: %.cc
@echo $@
@mkdir -p $(@D)
@$(CC) $(FLAGS) -c $< -o $@
$(OBJ_CXX_DIR)/%.o: %.cpp
@echo $@
@mkdir -p $(@D)
@$(CC) $(FLAGS) -c $< -o $@
$(OBJ_CXX_DIR)/%.o: %.hpp
@echo $@
@mkdir -p $(@D)
@$(CC) $(FLAGS) -c $< -o $@
#链接目标文件
-include $(DEPENDS)
$(TARGET): o_describe $(OBJECTS)
@echo "======================== Generate Target File ========================"
ifeq (static,$(TYPE)) # 静态库
@$(AR) -r $(BUILD_DIR)/$@ $(OBJECTS)
else
@$(CC) $(FLAGS) -o $(BUILD_DIR)/$@ $(OBJECTS) $(LIB_FLAGS)
endif
@echo 'Build "$(BUILD_DIR)/$@" OK ...'
#只清除[.d .o]文件
clean:
@rm -rf $(OBJ_C_DIR) $(OBJ_CXX_DIR)
@echo "Clean OK ..."
#清除所有构建生成的文件
veryclean:
@rm -rf $(BUILD_DIR)
@echo "Very Clean OK ..."
#重新构建
rebuild: clean all
#安装到指定目录
install:
ifeq ($(BUILD_DIR)/$(TARGET), $(wildcard $(BUILD_DIR)/$(TARGET)))
@mkdir -p $(SET_PATH)
@cp $(BUILD_DIR)/$(TARGET) $(SET_PATH)/$(TARGET)
@echo "Install to '$(SET_PATH)' OK ..."
else
@echo "Install Fail, '$(BUILD_DIR)/$(TARGET)' no exist ..."
endif
Linux通用Makefile
于 2019-09-26 14:15:00 首次发布