Simple makefile:Linux C
概述
编写Linux C程序,Makefile文件是无法绕过去的。简单记录一下Makefile的知识,留作备忘。
原理
Linux C程序,是经过编辑、预处理、编译、链接等阶段会生成最终的可执行程序。
简单开发Linux C程序,可以使用gcc命令直接编译程序文件生成可执行文件或静态/动态链接库。
但复杂项目有较多的源文件,每次手动敲gcc编译命令容易出错,也较为浪费时间,故此时需要使用makefile文件,来帮助我们编译程序。
makefile文件定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
makefile文件编写完成:
- 可在同级目录下执行 make 命令,直接执行makefile中的脚本(若直接使用make命令,则同级目录下makefile文件必须名为makefile或Makefile);
- 也可以使用-f 来执行makefile文件,如 make -f /home/src/makefile(借助-f 参数时,makefile文件可任意命名);
测试代码
- head.h
- func1.c
- func2.c
- sum.c
- main.c
makefile 版本1
makefile规则:makefile由一组规则组成,如下所示:
目标: 依赖
(tab)命令
解释:
makefile规则三要素:
- 目标:要生成的目标文件(可执行文件、库文件、中间文件等)
- 依赖:目标文件由哪些文件生成
- 命令:通过执行该命令由依赖文件生成目标文件
例如:
makefile 版本2
改进:目标文件可一次生成,也可先将中间文件生成,然后再生成目标文件,减少出错率。
例如:
makefile 版本3
改进:项目中可能存在多个源文件,且makefile文件中同样的文件名称出现多次,不利于高效率编写makefile文件,故可使用makefile提供的变量来优化makefile的编写过程。
makefile变量类似于C语言中的宏定义,可以使用变量进行内容替换,提升makefile编写效率,且使之更容易维护。
makefile变量分为三种:
- 普通变量
- 自带变量
- 自动变量
普通变量:
- 变量定义使用 =
- 使用变量值 $(变量名)
自带变量:
- CC: gcc
- CPPFLAGS: C预处理的选项 -I
- CFLAGS: C编译器的选项 -Wall -g -c
- LDFLAGS: 链接器选项 -L -I
自动变量:
- $@: 表示规则中的目标
- $<: 表示规则中的第一个条件
- $^: 表示规则中的所有条件,组成一个列表,以空格隔开,若这个列表中有重复的项,则消除重复项
例如:
makefile 版本4
改进:项目中有众多的源文件,虽然上一版本中自定义的普通变量objects列出了所有的目标文件所需的中间文件,但依然容易出错,此时可使用makefile提供的函数,以一定的规则查找所有源文件和进行查找结果的字符替换。
- src =$(wildcard *.c):使用wildcard函数,可查找某路径下所有*.c文件;
- objects = $(patsubst %.c, %.o, $(src)):使用patsubst函数可以将src变量值中所有的后缀为.c的字符串替换为后缀为.o的字符串;
例如:
此时,便得到了一个仅需要修改target变量和src中源文件路径的makefile文件,具有普适性。
makefile 最终版本
改进:上一版本随具有普适性,但每次执行完makefile生成的文件(目标文件、中间文件等),还需手动删除,此时可使用makefile提供的伪目标,来达到一键删除makefile生成的文件的目的。
- .PHONY: 伪目标名称: 可在makefile文件中声明伪目标,执行"make 伪目标名称"命令(如下示例中:make clean),即可跳过前面版本中要生成目标文件的命令,只执行伪目标;
如下所示: