Linux通用Makefile

本文详细介绍了一个Makefile配置示例,涵盖了从参数设置到构建流程的各个环节,包括目标文件名、类型、编译器选项、依赖管理和构建规则等关键信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

##################################################
################ 可修改和配置参数 ################
##################################################
#目标文件名,例如: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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值