接上一篇:linux_GDB调试学习(调试运行、多文件设置断点)_C/C++程序调试
本次来分享linux下的makefile文件的编写,开始上菜:
使用前请安装make,安装命令:sudo apt install make
①要么第一个字母大写,剩余字母小写,例如:Makefile
②要么全部字母小写:makefile
①项目代码编译管理
②节省编译项目的时间
③一次编写终身受益
(1)格式:
目标:依赖
(tab)命令
(2)解释:
目标 --> 要生成的目标文件
依赖 --> 生成目标文件需要的一些文件
命令 --> 借助依赖文件生成目标文件的手段
tab --> 缩进,在第二行开始
Makefile会把规则中的第一个目标作为终极目标
app:依赖 #指定生成的最终目标为app
写该用例前请自己先创建add.c、sub.c、main.c源文件,否则执行makefile的时候会出错。
创建一个makefile文件,在其中添加如下内容:
mycalc:add.c sub.c main.c -o mycalc
gcc add.c sub.c main.c -o mycalc
#该代码功能:(在makefile文件中用#进行注释)
#执行gcc add.c sub.c main.c -o mycalc
命令,生成mycalc可执行文件
①若想生成目标,检查规则中的依赖条件是否存在,
②如果不存在,寻找是否有规则用来生成该依赖文件
③检查规则中的目标是否需要更新,必须检查它的所有依赖,
④依赖中有任意一个被更新,则目标必须更新
⑤依赖文件比目标文件时间晚,则需要更新
make怎么知道哪个文件被更新了?
make根据文件修改的时间来进行对比的,源文件生成的时间<.o生成的时间<最终目标生成的时间,这样就知道哪个文件被修改了,可看用例二。
写该用例前请自己先创建main.c、add.c、sub.c、mul.c源文件,否则执行makefile的时候会出错。
创建一个makefile文件,在其中添加如下内容:
app:main.o add.o sub.o mul.o
gcc main.o add.o sub.o mul.o -o app
main.o:main.c
gcc -c main.c
add.o:add.c
gcc -c add.c
mul.o:mul.c
gcc -c mul.c
sub.o:sub.c
gcc -c sub.c
解释说明:
①make先检查main.o add.o sub.o mul.o是否存在,若是不存在,则会向下寻找是否有用来生成该依赖条件的文件;
②第4行到第14行都是对第一行的依赖条件的生成,make就会去找这些行依赖;
③使用该种方法,第一次编译后,若是main.c或者其他某单个文件被修改(make会对比文件修改的时间),只会编译对应的单个文件,就不会全部文件都被编译一次,这样更节省时间。
注意:生成终极目标的规则一定要写在第一行,在这里app就是我们需要生成的终极目标,若是写在其他行,我们的终极目标就变了。
make的执行命令如下:
make #makefile文件的路径下,终端执行命令:
make +objname #执行makefile文件中的objname目标
使用方法请看用例三
写该用例前请自己先创建main.o、add.c、sub.c、mul.c源文件,否则执行makefile的时候会出错。
创建一个makefile文件,在其中添加如下内容:
app:main.o add.o sub.o mul.o
gcc main.o add.o sub.o mul.o -o app
main.o:main.c
gcc -c main.c
add.o:add.c
gcc -c add.c
mul.o:mul.c
gcc -c mul.c
sub.o:sub.c
gcc -c sub.c
clean:
rm main.o add.o sub.o mul.o
这个时候,终端执行命令:
make
#是编译.c文件
终端执行命令:
make clean
#就会删除掉main.o add.o sub.o mul.o这四个文件。
问题1:
如果当前目录下有同名clean文件会怎么样?
答:报错:clean已是最新,即不执行clean对应的命令。
解决方案:
添加伪目标声明代码:.PHONY:clean
makefile文件中的代码更改如下:
app:main.o add.o sub.o mul.o
gcc main.o add.o sub.o mul.o -o app
main.o:main.c
gcc -c main.c
add.o:add.c
gcc -c add.c
mul.o:mul.c
gcc -c mul.c
sub.o:sub.c
gcc -c sub.c
.PHONY:clean #伪目标声明
clean:
rm main.o add.o sub.o mul.o -f #-f是强制执行这个命令,无论有没有这些.o文件
这样就不会出现上述问题了。
问题2:
在执行makefile的时候,当你执行完一条命令出错后,就不会在执行剩下的命令了,这时候,我们在命令的前面加入特殊-,表示此条命令出错,make也会继续执行后续的命令。如:“-rm a.o b.o”
变量定义及赋值:obj = a.o b.o c.o
变量取值:fobj = $(obj)
由 Makefile 维护的一些变量,通常格式都是大写
例如:
CC =cc #系统变量CC默认为cc,也就是gcc
有些有默认值,有些没有
CPPFLAGS : 预处理器需要的选项 如:-I
CFLAGS:编译的时候使用的参数 –Wall –g -c
LDFLAGS :链接库使用的选项 –L -l
用户可以修改这些变量的默认值
CC = gcc
(请看用例四。)
1、自动变量规则:
$@ #规则中的目标
$< #规则中的第一个依赖条件
$^ #规则中的所有依赖条件
都是在规则中的命令中使用
2、模式规则
在规则的目标定义中使用 %
在规则的依赖条件中使用 %
3、示例:
%.o:%.c
$(CC) –c $< -o $@
$< #表示依次取出依赖条件
$@ #表示依次取出目标值
% #表示一个或者多个
$^ #规则中的所有依赖
如图:
(请看用例四。)
现将用例三中makefile的代码做如下修改:
obj=main.o add.o sub.o mul.o
target=app
CC = gcc
$(target):$(obj)
$(CC) $(obj) -o $(target)
%.o:%.c
$(CC) -c $< -o $@
.PHONY:clean #伪目标声明
clean:
rm main.o add.o sub.o mul.o -f
(这样一写是不是就看着简洁很多了~~)
执行的功能效果和用例三是一样的。
makefile中所有的函数必须都有返回值,在这里介绍两个常用的函数。
查找指定目录下指定类型的文件,该函数有一个参数
用法:src = $(wildcard ./src/*.c)
#找到./src 目录下所有后缀为.c的文件,赋给变量src,其中./src/*.c就是该函数的参数了
匹配替换,从src中找到所有.c 结尾的文件,并将其替换为.o
用法:
#把src变量中所有后缀为.c的文件替换成.o
obj = $(patsubst %.c ,%.o ,$(src))
#指定.o 文件存放的路径 ./obj/%.o
obj = $(patsubst %.c, ./obj/%.o, $(src))
注意:在写目标的时候,也需要加上路径
./obj/%.o:%.c
当然,makefile的函数肯定不止这些,这里只是介绍两个常用的。
现将用例四中makefile的代码做如下修改:
target=app
src=$(wildcard ./*.c)
obj=$(patsubst ./%.c, ./%.o, $(src))
CC = gcc
$(target):$(obj)
$(CC) $(obj) -o $(target) -I./1
%.o:%.c
$(CC) -c $< -o $@
.PHONY:clean #伪目标声明
clean:
rm main.o add.o sub.o mul.o -f
(执行的功能效果和用例四是一样的。)
以上就是本次的分享了,希望对广大网友有帮助。
此博主在CSDN发布的文章目录:【我的CSDN目录,作为博主在CSDN上发布的文章类型导读】