第八章 内存管理系统
makefile
-
编译整个项目,如果改变局部关系,只靠人工难以维护文件间的依赖关系,所以通过make程序进行处理
-
makefile文件是make程序的搭档:发现某个文件更新后,只编译该文件和受该文件影响的相关文件,其他不受影响的文件不重新编译,从而提高了编译效率
- makefile文件类似于脚本程序,定义了各种关键字、语法结构、函数、变量
- make程序通过解析makefile文件后,自动找出变更的文件以及依赖此变更文件的相关文件,然后对所有受影响的相关文件执行事先定义好的命令规则
-
makefile基本语法
// 一组规则 目标文件(输出):依赖文件(输入) [Tab]命令(规则)
- 目标文件:指规则中想要生成的文件,可以是
.o
文件、可执行文件或者伪目标 - 依赖文件:生成此规则中目标文件所需要的文件
- 命令:一个或多个shell命令,其中每条命令必须以Tab开头,单独占一行
- 目标文件:指规则中想要生成的文件,可以是
-
make程序通过文件的属性和数据相关的时间戳进行判断更新部分
- atime:即access time,表示访问文件数据部分时间,每次读取文件数据部分时就会更新atime,比如cat或less命令会进行更新,而ls命令则不会
- ctime ,即change time ,表示文件属性或数据的改变时间,每当文件的属性或数据被修改时,就会更新ctime,也就是说ctime 同时跟踪文件属性和文件数据变化的时间。
- mtime ,即modify time,表示文件数据部分的修改时间,每次文件的数据被修改时就会更新mtime 。在上面说过啦, ctime 也跟踪数据变化时间,所以,当文件数据被修改时, mtime 和ctime 一同更新。
-
默认makegile文件查找次序
- GNUmakefile
- makefile
- Makefile
-
伪目标:规则中不存在依赖文件的一组规则,不能和真实目标同名
-
约定俗称的伪目标名称
伪目标名称 功能描述 all 完成所有模块的编译工作,类似于rebuild all clean 用于清空编译完成的所有目标文件, 一般用rm 命令实现 dist 用于将打包文件后的tar 文件再压缩成gz 文件 install 将编译好的程序复制到安装目录下,通过prefix参数配置 printf 用于打印已经发生改变的文件 tar 用于将文件打包成tar 文件,也就是所谓的归档文件 test 用于测试makefile流程 -
递归式推导目标:检查最终输出的目标文件,没有则向上查找制作该文件的规则进行执行。如果没有显式写命令,可能进行自动推导
-
makefile变量定义
变量格式定义:变量名 = 值(字符串,不用加引号) 变量名引用格式:$(变量名)
-
make还自定义一些系统级变量,可分为命令相关变量和参数相关变量
变量名 描述 AR 打包程序,默认是“ar” AS 汇编语言编译器,默认是“as” CC C语言编译器,默认是“cc” CXX C++语言编译器,默认是“g++” CPP C预处理器,默认是“$(CC)- E FC Fortran的编译器和预处理器 GET 从SCCS文件中提取文件程序 PC pascal语言编译器 MAKEINFO 将texinfo文件转换成info文件 RM 删除命令 TEX 从TeX源文件中创建TexDVI文件的程序 WEAVE 将Web转换为TeX程序 YACC 将处理的C程序转换为Yacc词法分析器 YACCR 处理Ratfor程序的Yacc此法分析器 ------ 参数相关的系统变量 ARFLAGS 打包程序$(AR)的参数 ASFLAGS 汇编语言编译器参数 CFLAGS c 语言编译器参数 CXXFLAGS C++编译器参数 CPPFLAGS C 预处理器参数 FFLAGS Fortran 语言编译器参数 LDFLAGS 链接器参数 PFLAGS Pascal 语言编译器参数 YFLAGS Yacc 词法分析器参数 -
在编写规则时,若一行写不下,可以在行尾添加反斜杠字符’\',这样下一行的内容便被认为是同一行
-
makefile 中用#来单行注释,只要各行第一个非空字符(除空格、tab )是#,本行内容便被注释了
-
make all命令可以查看make程序执行过程
-
隐含规则可推导最终的可执行文件
- C程序:x.o的生成依赖于x.c,生成x.o的命令
$(CC) - c ${CPPFLAGS) ${CFLAGS)
- C++程序:x.o的生成依赖于x.cc,生成x.o的命令
$(CXX) -c $ (CPPFLAGS) $(CFLAGS)
- Pascal程序:x.p的生成依赖于x.p,生成x.o的命令
$(PC) -c $ (CPPFLAGS) $(CFLAGS)
- C程序:x.o的生成依赖于x.c,生成x.o的命令
-
自动化变量代表一组文件名,值的范围是文件名集合
- $@:表示规则中的目标文件名集合,$@表示其中一个目标文件名
- $<:表示规则中依赖文件的第一个
- $^:表示规则中依赖文件的集合
- $?:表示规则中,所有比目标文件mtime更新的依赖文件集合
-
模式规则
- %用来匹配任意多个非空字符。g%.o 是以字符g 开头的所有以.o为结尾的文件
-
makefile示例
#无省略 test2.o:test2.c gcc -c -o test2.o test2.c test1.o:test1.c gcc -c -o test1.o test1.c test.bin:test1.o test2.o gcc -o test.bin test1.o test2.o all: test.bin @echo "compile done" # 变量定义 test2.o:test2.c gcc -c -o test2.o test2.c test1.o:test1.c gcc -c -o test1.o test1.c objfiles = test1.o test2.o test.bin:$(objfiles) gcc -o test.bin $(objfiles) all: test.bin @echo "compile done" # 使用自动化变量 test2.o:test2.c gcc -c -o test2.o test2.c test1.o:test1.c gcc -c -o test1.o test1.c objfiles = test1.o test2.o test.bin:$(objfiles) gcc -o $@ $^ all: test.bin @echo "compile done" # 模式匹配 %.o:%.c gcc -c -o $@ $^ objfiles = test1.o test2.o test.bin:$(objfiles) gcc -o $@ $^ all:test.bin @echo "compile done"
实现assert断言
- 系统越复杂,模块越多越容易出错。为了方便调试,一个好的习惯是在关键部分设置哨兵进行监测数据的合法性
- 在C语言中ASSERT是用宏来定义的,其原理是判断传给ASSERT 的表达式是否成立,若表达式成立则什么都不做,否则打印出错信息并停止执行,我们仿照它来实现自己的版本。
的习惯是在关键部分设置哨兵进行监测数据的合法性
2. 在C语言中ASSERT是用宏来定义的,其原理是判断传给ASSERT 的表达式是否成立,若表达式成立则什么都不做,否则打印出错信息并停止执行,我们仿照它来实现自己的版本。
[外链图片转存中…(img-bv93JnTk-1677658749817)]