前言
上篇Demo执行文件的编译,直接参考了网上通用的Makefile万能模版,也算是一种简单的应用实践了。这篇开始考虑随着Demo开发工作推进,源码文件增多,甚至目录结构调整的场景。在这个场景下,Makefile的扩展性会显得十分必要,因为理想的目标是要能够让开发人员对Makefile进行最少、最傻瓜式的修改(甚至做到不修改)就能继续保持Demo编译工作的顺畅。因此,我们的工作应该是实现一套简单易使用的编译框架,使得开发同事只需在这个框架上依样画葫芦,就能实现对增删文件or目录的编译。最后,还有一点很重要的就是,一定要保证不能每次都全量编译,即只对最新的修改及其相关依赖的文件进行编译。(全量编译对于大型项目不可接受!再做强调!)
源码目录调整
源码文件及所在目录结构有细小调整安排,理由就不说了,我想但凡功能规划明确的项目,即便功能模块或源码文件都增多,以下这种源码目录结构的安排也算是典型通用的。该目录结构的变动,会直接导致原来的Makefile也需要重新调试,单一Makefile虽然编写简单,但不易维护,在这就体现了弊端。至于怎么由单一Makefile变成多Makefile的过程,我也直接跳过了,只能说这是实践后的结果,具体如下图:
Makefile改动
针对变动后的Makefile内容,如下,有必要的在源码中注释。
#./demo_prj_v1.1/Makefile
# ---------------------------------------------------------------------------
#
# Make for demo
#
# ---------------------------------------------------------------------------
# CROSS_COMPILE ?= xxx-linux-gnu-
CROSS_COMPILE ?=
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
AR = $(CROSS_COMPILE)ar
LD = $(CROSS_COMPILE)ld
OBJCOPY = $(CROSS_COMPILE)objcopy
export CC LD
# shell命令,这样可以做到全局可控
ECHO = @echo
MKDIR = mkdir -p
RM = @rm -rf
MAKE = make -j # -j支持并行编译
export ECHO MKDIR RM
# ---------------------------------------------------------------------------
# Compiler dir_env define
# ---------------------------------------------------------------------------
TOP_DIR := $(shell pwd)
BUILD_DIR := $(TOP_DIR)/build
BIN_DIR := $(BUILD_DIR)/bin
OBJS_DIR := $(BUILD_DIR)/objs
# Attempt to create a output target directory.
$(shell [ -d ${BUILD_DIR} ] || $(MKDIR) ${BUILD_DIR} && $(MKDIR) ${OBJS_DIR} && $(MKDIR) ${BIN_DIR})
export TOP_DIR OBJS_DIR
# ---------------------------------------------------------------------------
# OBJS include the necessary directories and the source files
# ---------------------------------------------------------------------------
SUB_DIRS = public lib demo
ALL_OBJS = $(addprefix $(OBJS_DIR)/, $(addsuffix .o, $(SUB_DIRS)))
INCLUDE = -I$(TOP_DIR)/public/include \
-I$(TOP_DIR)/lib/include \
-I$(TOP_DIR)/demo/include
export INCLUDE
CFLAGS = -g
.PHONY: all clean $(SUB_DIRS)
all: $(BIN_DIR)/demo_app
$(BIN_DIR)/demo_app: $(ALL_OBJS)
$(ECHO) Build demo_prj start..