##############################################################################
# 简易多模块程序自动编译/清除Makefile
#简介: 自动编译、清除功能,不需要每次编译输入gcc或者rm指令
#使用方法: $make [OBJ=obj1.suffix[:obj2[:...]]] [TARGET=tool] [clean]
#
#使用说明:执行make指令将编译/清除 $(SRC)/obj1.suffix $(SRC)/obj2.suffix ...
# 如果是make exec指令,则生成可执行程序$(BIN)/tool
# 如果是make gdb指令,则启动调试器调试可执行程序$(BIN)/tool
# 如果不指定TARGET,将默认使用obj1(第一个OBJ的前缀名)作为输出可执行程序名。
#
#注意事项:1.Makefile不检查任何路径,请确保您指定的各路径有效
#
#示例: 1.$make OBJ=main.c:lib1:lib2 TARGET=tool
# 将编译$(SRC)/main.c $(SRC)/lib1.c $(SRC)/lib2.c三个文件
# 生成$(BIN)/main.o $(BIN)/lib1.o $(BIN)/lib2.o目标程序,
# 并连接三个目标程序生成可执行程序$(BIN)/tool
#
# 2.$make OBJ=main.c:lib1:lib2 TARGET=tool clean
# 将清除$(BIN)/main.o $(BIN)/lib1.o $(BIN)/lib2.o和$(BIN)/tool
#
# Author: WKF4058, Date: 2013/12/30
#修改历史:
# 2014-1-9:添加2个编译过程中间输出文件:预处理.i,编译.s
##################用户配置选项################################################
#指定编译器
CC = gcc
CXX = g++
#指定默认源码后缀名
SUFFIX = .c
#指定调试器
GDB = `which gdb`
#指定编译参数gdb调试信息
CFLAGS = -g
#目标程序名,支持多个OBJ,多个OBJ请使用:分割,请在make指令后接参数指定OBJ
#例如最简单的编译test.c 则应使用[user@thinkpad]$ make OBJ=test.c
OBJ = test.c
#可执行文件名,如果不指定,则默认与首个目标程序前缀同名,无后缀名
TARGET =
#输出目标程序目录,最后一个/可写可不写
BIN = ./bin
#源程序文件目录,最后一个/可写可不写
SRC = ./src
#自定义包含文件的搜索路径,以:分割,最后一个/可写可不写
VPATH += ./:./include
##############################################################################
##########make处理部分,非专业人士请勿擅自修改######################################
#如果BIN为空,则将BIN指定为当前目录
ifeq ($(BIN),)
BIN := ./
endif
#如果参数指定了第一个目标的后缀名,则使用该后缀名作为源码后缀名
ifeq ($(suffix $(word 1,$(OBJ))), )
else
SUFFIX := $(suffix $(word 1, $(OBJ)))
endif
#根据源码重设编译器
ifeq ($(SUFFIX),.cpp)
CC := $(CXX)
endif
ifeq ($(SUFFIX),.cc)
CC := $(CXX)
endif
#删除路径后面的斜线,并转换为路径序列
VPATH := $(patsubst %/,%,$(subst :, ,$(VPATH)))
BIN := $(patsubst %/,%,$(BIN))
#设置包含文件搜索路径
CFLAGS += $(addprefix -I,$(VPATH))
#如果SRC为空,则将SRC指定为当前目录
ifeq ($(SRC),)
SRC := ./
endif
#拼装目标程序名
override OBJ := $(addsuffix .o,$(subst :, ,$(basename $(OBJ))))
#如果未指定可执行程序名或指定了空TARGET,则采用第一个OBJ的前缀名作为可执行程序名
ifeq ($(TARGET),)
override TARGET := $(basename $(firstword $(OBJ)))
endif
#Makefile总入口
all: $(BIN)/$(TARGET)
#连接全部目标程序,生成可执行程序
$(BIN)/$(TARGET): $(addprefix $(BIN)/,$(OBJ))
$(CC) $(CFLAGS) $+ -o $@
#单独分步编译每个指定的目标程序
$(addprefix $(BIN)/,$(OBJ)): $(BIN)/%.o : $(SRC)/%$(SUFFIX)
$(CC) -E $(CFLAGS) $< -o $(patsubst %.o,%.i,$@)
$(CC) -S $(CFLAGS) $(patsubst %.o,%.i,$@) -o $(patsubst %.o,%.s,$@)
$(CC) -c $(CFLAGS) $(patsubst %.o,%.s,$@) -o $@
#执行可执行程序
exec:
$(BIN)/$(TARGET)
#调试可执行程序
gdb:
$(GDB) $(BIN)/$(TARGET)
#清除编译结果
clean:
@echo Cleaning build...
rm -rf $(BIN)/$(TARGET) $(addprefix $(BIN)/,$(OBJ))
rm -rf $(patsubst %.o,$(BIN)/%.i,$(OBJ)) $(patsubst %.o,$(BIN)/%.s,$(OBJ))
##########################END#################################################