整理项目的makefile,顺便对其写法简单归纳整理如下。这种写法乍一看让人比较晕,定义的规则和宏比较多,貌似有点累赘。
但是如果项目比较大的话,这种写法有利于统一项目生成规则(相同类型的文件都用相同的处理规则),减少makefile编写的工作量(不需要自己编写规则,只需要提供文件列表),同时也减少了出错的概率。比较规范和灵活通用,值得借鉴。
这种写法把Makefile分为通用规则定义文件和工程定义文件两部分
------------------------------------------------------------
[com.mk通用规则定义文件]
CC = gcc
#.SUFFIXES定义符合编译规则的扩展文件类型,.c/.h/.cxx已经被默认支持。
#示例增加了.d文件(Pro*C文件.pc也可以如此处理)
.SUFFIXES: .d
#定义相同类型文件对应的统一规则
.c.o: #定义如何从.c生成.o的规则
@echo '--'$*.c #写这一行,可以打印出被处理的文件
$(CC) -o $*.o -c $*.c # 生成.o的语句
.d.c: #定义如何从.d文件生成.c文件的规则
@echo '--'$*.d #写这一行,可以打印出被处理的文件
cp $*.d $*.c #生成.c文件的语句
.d.o: #定义如何从.d文件生成.o文件的规则
@echo '--'$*.d #写这一行,可以打印出被处理的文件
cp $*.d $*.c #因为本例中是要调用c编译器,所以先生成.c文件
$(CC) -o $*.o -c $*.c #再从.c文件生成.o
#定义编译入口
all:build
# 下面这句定义了需要从哪些源文件(CFILE/DFILE所定义的列表)
#和什么规则(.c=.o即从.c生成.o; .d=.o表示从.d生成.o)生成目标文件
ALLOBJS =$(CFILE:.c=.o) $(DFILE:.d=.o)
#编译命令,表示先编译目标对象,再输出可执行文件
$(EXE):$(ALLOBJS)
$(CC) -o $@ $(ALLOBJS)
#清除语句,同样是利用了规则定义,
clean:
rm -f $(DFILE:.d=.o) $(DFILE:.d=.c)
rm -f $(CFILE:.c=.o)
rm -f $(EXE)
------------------------------------------------------------
[makefile代码目录下的工程定义文件]
#定义输出目标名称
EXE=testexe
#以下只需要提供文件列表和定义编译目标
CFILE=m.c #定义C源文件列表,可以有多个
DFILE=testd.d teste.d #定义D源文件列表,可以有多个
#给编译入口赋值
build: $(EXE)
COMMPATH=./ #指定模版所在路经
include $(COMMPATH)/com.mk #包含通用模版文件,make会调用通用模版里的规则,进行编译