Linux系统——Makefile、gdb和文件IO
一、Makefile
1.基本语法
makefile由一组规则组成,规则如下:
目标: 依赖
(tab)命令
makefile基本规则三要素:
- 目标: 要生成的目标文件
- 依赖: 目标文件由哪些文件生成
- 命令: 通过执行该命令由依赖文件生成目标
比如:
main:main.c fun1.c fun2.c sum.c
gcc -o main main.c fun1.c fun2.c sum.c -I./
基本原则:要想生成目标,检查规则中的所有依赖文件是否存在,如果有的依赖文件不存在,则向下搜索规则,看是否有生成该依赖文件的规则,如果有规则用来生成该依赖,则执行规则中的命令生成依赖文件,如果没有规则用来生成该依赖文件,则报错。如果依赖中的文件都存在,检查规则中的目标是否需要更新时,必须先检查它的所有依赖,依赖中的任何一个被更新,则目标必须更新。检查规则是哪个时间大哪个最新。比如:目标的时间>依赖的时间,则不更新;目标的时间<依赖的时间,则更新。
2.使用变量
普通变量:定义直接用=,使用的时候用$(变量名)
自带变量:Makefile提供的变量:全部大写
CC = gcc
CPPFLAGS:C预处理的选项 -I
CFLAGS:C编译器的选项 -Wall -g -c
LDFLAGS:链接器选项-L -I
自动变量:
- $@: 表示规则中的目标
- $<: 表示规则中的第一个条件
- $^: 表示规则中的所有条件, 组成一个列表, 以空格隔开, 如果这个列表中有重复的项则消除重复项。
3.Makefile函数
1. wildcard – 查找指定目录下的指定类型的文件 src=$(wildcard *.c) //找到当前目录下所有后缀为.c的文件,赋值给src 2. patsubst – 匹配替换 obj=$(patsubst %.c,%.o, $(src)) //把src变量里所有后缀为.c的文件替换成.o
src=$(wildcard *.c) 等价于src=main.c fun1.c fun2.c sum.c
obj=$(patsubst %.c,%.o, $(src))等价于obj=main.o fun1.o fun2.o sum.o
4.Makefile清除操作
用途: 清除编译生成的中间.o文件和最终目标文件
make clean 如果当前目录下有同名clean文件,则不执行clean对应的命令, 解决方案:
- 伪目标声明:
.PHONY:clean
声明目标为伪目标之后, makefile将不会检查该目标是否存在或者该目标是否需要更新
clean命令中的特殊符号:
- “-”此条命令出错,make也会继续执行后续的命令。如:“-rm main.o”
rm -f: 强制执行, 比如若要删除的文件不存在使用-f不会报错
- “@”不显示命令本身, 只显示结果。如:“@echo clean done"
其它
– make 默认执行第一个出现的目标, 可通过make dest指定要执行的目标
– make -f : -f执行一个makefile文件名称, 使用make执行指定的makefile: make -fmainmak
命令行直接make执行,默认执行第一个目标也就是main,如果第二次编译需要删除前一次,执行make clean。
如果当前路径下有不止一个Makefile,使用make -f +Makefile文件名的形式来执行这个Makefile文件。
二、gdb调试
gdb是gcc的调试工具,功能强大,可以完成四方面功能:
1.启动程序,按照自定义的要求随心所欲的运行程序
2.可让被调试的程序在你所指定的断点处停住
3.当程序被停住,可以检查此时程序中发生的事
4.动态的改变你程序的执行环境
gdb调试在单线程的时候可以使用,多线程的时候很麻烦,还是通过打印信息的形式调试。
特别注意,使用gdb调试的时候需要加-g参数。
三、文件IO
Linux的内核使用C语言写的。
1.c语言操作文件相关问题:
使用fopen函数打开一个文件, 返回一个FILE* fp, 这个指针指向的结构体有三个重要的成员.
- 文件描述符: 通过文件描述可以找到文件的inode, 通过inode可以找到对应的数据块
- 文件指针: 读和写共享一个文件指针, 读或者写都会引起文件指针的变化
- 文件缓冲区: 读或者写会先通过文件缓冲区, 主要目的是为了减少对磁盘的读写次数, 提高读写磁盘的效率.
2.库函数和系统函数的关系
库函数和系统函数是调用和被调用的关系,库函数是系统函数的进一步封装。
系统调用:是操作系统实现并提供给外部应用程序的编程接口。
3.虚拟地址空间
Linux每一个运行的程序(进程)操作系统都会为其分配一个0~4G的地址空间(虚拟地址空间)。
0~3G用户区,3G~4G内核区:
操作系统管理内核空间,用户不能操作。
内核区很重重要的一个就是进程管理,进程管理中有一个区域就是PCB,本质是一个结构体,PCB中有一个文件描述符表,其中存放着进程打开的文件描述符,涉及到的文件IO操作都会用到这个文件描述符。
默认情况程序启动至少打开了三个文件:标准输入0、标准输出1和标准错误输出2。
每打开一个新的文件,占用一个新的描述符,而且是空闲的最小的一个文件描述符。
一个进程最多可以打开0~1023总共1024个文件,这取决于文件描述符表的大小。
一个进程有一个文件描述符表:1024
- 前三个被占用, 分别是STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO
- 文件描述符作用:通过文件描述符找到inode, 通过inode找到磁盘数据块.
虚拟地址空间——>内核区——>PCB——>文件描述表——>文件描述符——>文件IO操作使用文件描述符。