一个很简单的Makefile模板

原文:http://blog.163.com/shi_shun/blog/static/2370784920106198610771/

# 我的一个很简单的Makefile模板
# 每次自己写的一些小程序,都用这个改改,时间长了居然都忘了一些
# 具体的含义,这里就来一个中文完全注释版吧


CC=gcc
#########################################################
# 递归展开式变量:
# 缺点1:使用此风格的变量定义,可能会由于出现变量递归定义而导致make陷入到无限的变量展开过程中,
    最终使make执行失败.
# 缺点2:这种风格的变量定义中如果使用了函数,那么包含在变量值中的函数总会在变量被引用的地方执行
  (变量被展开时)
#########################################################

SRC = main.c 
         code.c 

TARGET = conv    

OBJ := $(SRC:.c=. o)
#########################################################
# 直接展开式变量
# 在使用“:=”定义变量时,变量值中对其他变量或者函数的引用在定义变量时被展开(对变量进行替换)

# 变量的替换引用,格式为“$(VAR:A=B)”(或者“${VAR:A=B}”),意思是,替换变量“VAR”中所有“A”字符结尾的
    字为“B”结尾的字。
# “结尾”的含义是空格之前(变量值多个字之间使用空格分开)而对于变量其它部分的“A”字符不进行替换
#########################################################


all:$(OBJ)
    $(CC) -DDEBUG -Wall -g -o $(TARGET) $(OBJ)
#########################################################
# 第一个规则,作为终极目标.“终极目标”就是当没有使用make 命令行指定具体目标时,make默认的更新的那一个目标。
#########################################################


%.o:%.c
    $(CC) -DDEBUG -Wall -g -o $@ -c $<
#########################################################
#在模式规则中,目标文件是一个带有模式字符“%”的文件,使用模式来匹配目标文件。文件名中的模式字符“%”
#
可以匹配任何非空字符 串, 除模式字符以外的部 分要求一致。

#在目标文件名中“%”匹配的部分称为“茎”。使用模式规则时,目标文件匹配之后得到“茎”,依赖根据“茎”产生对应的
#
依赖文件,这个 依赖文件 必须是存在的或者可 被创建的。

#此规则描述了一个.o文件如何由对应的.c文件创建。规则的命令行中使用了自动化变量“$<”和“$@”,其中,
#
自动化变量“$<”代 表规则的依赖 “$@”代表规则的 目标。此规则在执行时 ,命令行中的自动化变 量将根 据实际
#的目标和依赖 文件取对应值。
#########################################################

.PHONY:cle an
#########################################################
# 伪目标是这样一个目标:它不代表一个真正的文件名,在执行make
# 时可以指定这个目标来执行其所在规则定义的命令,有时也可以将
# 一个伪目标称为标签。
# 使用伪目标有两点原因:1. 避免在我们的Makefile中定义的只执行命
# 令的目标(此目标的目的为了执行执行一些列命令,而不需要创建
# 这个目标)和工作目录下的实际文件出现名字冲突。2. 提高执行make
# 时的效率。
#########################################################

clean:
    -rm -f $(OBJ)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# 下面的变量可以在shell 的环境变量里面指定。
# 也可以象下面这样在 Makefile 里面指定。
# CC=gcc                                          # 编译器
# CFLAGS=-Wall -Werror -g           # 编译器参数
# LD=gcc                                          # 连接器参数
# LDFLAGS= $(LIBS)  -lpthread      # 连接器参数
# DEPENDFLAG=-MM                   # 生成依赖关系文件的参数
# INCLUDES=-Idir1 -Idir2               # 指明包含外部头文件的目录
# LIBS=-la -lb -lc                              # 指明引用外部的库文件

CFLAGS:=$(CFLAGS) $(INCLUDES)
LDFLAGS:=$(LDFLAGS) $(LIBS)


#指明项目中,包含源程序的所有的子目录。
SRCDIRS=.
#指明最终生成的可执行文件的名称
PROGRAMS=test.exe


#下面的部分一般不用改动
#从所有子目录中得到源代码的列表
SRCS=$(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.c))


#得到源代码对应的目标文件的列表
OBJS=$(SRCS:.c=.o)

#得到源代码对应的依赖关系文件的列表依赖关系文件就是一个目标文件依赖于哪些头文件和源程序,

#依赖关系是自动生成的,并且用include语句包含在Makefile中

DEPENDS=$(SRCS:.c=.d)


#指明默认目标是生成最终可执行文件。
all: $(PROGRAM)


#生成依赖关系文件
%.d:%.c
        $(CC) $(DEPENDFLAG) $(CFLAGS)  $< |\
        sed "s?\\(.*\\):?$(basename $<).o $(basename $<).d :?g" \
        > $@ || $(RM) $@

$(PROGRAMS): $(OBJS)
        $(CC) $(LDFLAGS) -o $@ $(filter %.o ,$+)


# 包含入依赖关系文件
include $(DEPENDS)


# 删除生成的中间文件
clean:
        rm $(OBJS) $(DEPENDS) $(PROGRAMS)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Makefile通用模板CC=gcc
CFLAGS=-Wall

OBJPATH=obj                # .d文件和.o文件保存路径
TARGET=demo                # 最终可执行文件

default: $(TARGET)

SOURCE=a.c b.c                # 需要编译的.c文件
INCLUDE=

# 获取.d文件名集合
DEPS=$(addprefix $(OBJPATH)/, $(patsubst %.c, %.d, $(filter %.c, $(SOURCE))))
# 获取.o文件名集合
OBJS=$(addprefix $(OBJPATH)/, $(addsuffix .o, $(basename $(SOURCE))))

-include $(DEPS)

# 生成.d文件
$(OBJPATH)/%.d: %.c
    $(CC) $(INCLUDE) -MM $< | sed "1s|^|$(dir $@)|" |"
    sed "1{x;s|.*|$@: $<|;G;}" > $(basename $@).d

# 生成.o文件
$(OBJPATH)/%.o : %.c
    $(CC) $(CFLAGS) -o $@ -c $<

# 链接成可执行文件
$(TARGET): $(OBJS)
    $(CC) $(CFLAGS) -o $@ $^

# 清理
clean:
 rm -rf $(OBJPATH)/*.d $(OBJPATH)/*.o $(TARGET)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值