自己断断续续的结束了一段时间的makefile,想给自己写个小结,内容比较常用,可能不适合一些初学者看,但仅仅是像让自己以后记得回忆……
如果是初学makefile,推荐这个:搜索“跟我一起写Makefile”
1.make工具是一个开发工具 —— 主要功能包括:源代码管理 + 函数库管理
2.makefile的文件组成 —— 一组依赖关系 + 规则
依赖关系 —— 定义最终应用程序里的每个文件和源程序的关系
规则 —— 目标名称 + 冒号 + 空格或tab + 用空格或tab隔开的文件列表
a)若一次想创建多个文件,可利用伪目标all, 若未指定all, make命令只创建它在makefile中找到的第一个目标 ★★★
b)空格和tab是有区别的——规则所在的行必须以tab开头 ★★★
c)如果某一目标后面是空的(clean:),即无任何依赖关系,则该目标永远被执行
d)make命令在执行规则时会调用一个shell, 并且会针对每个规则使用一个新shell , 对于多条命令,如果需要在下一条命令之前检查前一条的执行情况,将这些命令用 &&连接起来 ★★★★★
(请理解以下的写法)
install:mypp
@if [ -d $(INSTDIR) ] ; \
then \
cp myapp $(INSTDIR); \
chmod a+x $(INSTDIR)/myapp; \
else \
echo "Sorry ^^^^^^"
fi
3.常用make命令的选项
-k —— 让make在发生错误时继续运行,而不是在检测到第一个错误后就停止;★★★
-n —— 让make命令输出要执行的步骤,但并没有真正的执行这些操作;
-f <filename> —— 告诉make命令,哪个文件作为makefile 文件;
4.宏定义
(makefile 用#进行注释)
宏通常在makefile中定义,也可以在命令行给出宏定义(make CC=c99)命令行的定义将覆盖makefile文件中的定义,但在makefile文件之外使用宏定义时,其必须以单个参数的形式传递,故应避免在宏定义中使用空格或下面给出的(make "CC = c99") ★★★
常用的宏定义名:
a) $(CC)、$(CFLAGS)、$(INCLUDE)等等,自己写的makefile中可用其他名字,但建议用这个,因为makefile默认规则中,宏名是这样的
b) $? —— 当前目标所依赖的文件列表中比当前目标文件要新的文件
$@ —— 当前目标名
$< —— 当前依赖文件的名字
$* —— 布包扣后缀名的当前依赖文件的名字
上述描述,其实有不少不准确的地方,以上是摘自《linux程序设计》一书,准确的请查看,博文开始推荐的“跟我一起写makefile”连接
c) - —— 告诉make命令忽略所有的错误 ★★★★★
@ —— 告诉make在执行某条命令时不要将该命令显示在STDOUT上
5.内置规则 + 后缀和模式规则
新增加一条后缀规则语法: .<old_suffix>.<new_suffix>
模式规则: %.<new_suffix>:%.<old_suffix>
上述两个是等价的
(内置规则很多,可自己学习)
6.管理库函数——make命令用特殊的语法来处理函数库
语法:lib(file.o) ——目标文件file.o是存储在函数库lib.a中的,这等同于
.c.a:
$(CC) -c $(CFLAGS) $<
$(AR) $(ARFLAGS) $@ $*.o
$(AR)和$(ARFLAGS)默认取值分别是ar 和 rv
7.makefile 文件和子目录
a) 第一个方法——在子目录中编写第二个makefile文件
mylib.a:
(cd myliddirectory; $(MAKE))
用()是确保他们被一个单独的shell处理——make会针对每个命令调用一个新的shell ★★★★★
b) 第二个方法——在原来的makefile中添加一些宏,新添加的宏通过我们已见过的宏的尾部追加一个字母得到,字母D代表目录,字母F代表文件名 ★★★★★
.c.o:
$(CC) $(CFLAGS) -c $(@D)/$(<F) -o $(@D)/#(@F)
8.GUNmake 和 gcc选项
-jN —— 允许make 同时执行N条命令,缩短重新编译的时间
gcc的-MM —— 产生一个适用于make命令的依赖关系清单(你只需把这个结果输出到临时文件,然后插入到makefile中)
gcc -MM main.c 2.c 3.c #自己尝试
目前就这么多,待以后修改……
最后推荐一个学习shell的好网站,自己是在那学的,很详细http://www.tldp.org/LDP/abs/html/