管理Linux环境下的大型项目,能够有一个智能的
Build
子系统会起到事半功倍的效果,本文描述
Linux
环境下大型工程项目子目录
Makefile
的一种通用写法,使用该方法,
当该子目录内的文件有增删时无需对
Makefile
进行改动
,可以说相当的智能。下面先贴代码(为了减少篇幅,一些非关键的代码被去掉):
-
ROOTDIR = .
-
-
EXE_DIR = ./bin
-
CFLAGS = -I$(INCLUDE_DIR) -I$(LIB_INC) -Wall
-
LFLAGS = -L$(LIB_DIR)
-
-
objects := $(patsubst %.c,%.o,$(wildcard *.c))
-
executables := $(patsubst %.c,%,$(wildcard *.c))
-
-
$(objects) : %.o: %.c
-
$(CROSS_COMPILE)gcc -c $(CFLAGS) $< -o $@
-
all
: $(executables)
-
$(executables) : $(objects)
-
@mkdir -p ./bin$
-
(CROSS_COMPILE)gcc $(CFLAGS) $< -o $(EXE_DIR)/$@ $(LFLAGS) $(LIBS)
-
clean:
-
@rm -f *.o rm -f ./bin/*
-
@rm -rf ./bin
-
distclean: clean
假如当前目录里面有
a.c b.c
两个文件
Makefile
里的函数跟它的变量很相似——使用的时候,你用一个 $ 符号跟开括号,函数名,空格后跟一列由逗号分隔的参数,最后 用关括号结束。例如,在
GNU Make
里有一个叫
‘wildcard’
的函数,它有一个参数,功能是展开成一列所有符合由其参数描述的文件名,文件间以空格间隔。像这个命令:
objects= $(wildcard *.c)
会产生一个所有以
‘.c’
结尾的文件的列表(本例
a.c b.c
),然后存入变量
objects
里。
另一个有用的函数是
patsubst ( patten substitude,
匹配替换的缩写
)
函数。它需要3个参数——第一个是一个需要匹配的式样,第二个表示用什么来替换它,第三个是一个需要被处理的由空格分隔的字列。例如,处理那个经过上面定义后的变量:
objects := $(patsubst %.c,%.o,$(wildcard *.c))
会被处理为:
objects := a.o b.o
同理:
executables := $(patsubst %.c,%,$(wildcard *.c))
会被处理为:
executables := a b
%o:
所有以
“.o”
结尾的目标
,
也就是
a.o b.o
依赖模式
“%.c”:
取模式
“%.o”的%,
也就是
foo bar,
并为其加上
.c
后缀,即
a.c,b.c
$<:
表示所有依赖集,也就是
a.c b.c
$@:
表示目标集,也就是
a.o b.o
命令前加
@,
表示在终端中不打印,如
@mkdir -p ./bin
$(objects) : %.o: %.c
$(CROSS_COMPILE)gcc -c $(CFLAGS) $< -o $@
即可翻译为:
a.o b.o : a.c b.c
$(CROSS_COMPILE)gcc -c $(CFLAGS) (a.c b.c) -o (a.o b.o)
明白了这些,这种
Makefile
的写法就可以完全掌握了
。