当前位置: 首页 > news >正文

Makefile的使用

Makefile的基本使用:

Makefile文件格式如下

# 放在第一个的是默认目标
# 目标是编译出main文件,依赖hello.o和main.o
# 编译的命令是gcc -o main hello.o main.o
main:hello.o main.ogcc hello.o main.o -o main# 目标是编译出main.o文件,依赖main.c
# 编译的命令是gcc -c main.c -o main.o/或gcc -c main.c 它会自动识别到名字并转换成main.o
main.o:main.cgcc -c main.c -o main.o# 目标是编译出hello.o文件,依赖hello.c
# 编译的命令是gcc -c hello.c -o hello.o/或gcc -c hello.c 它会自动识别到名字并转换成hello.o
hello.o:hello.cgcc -c hello.c -o hello.o

使用方法:

itcai@LAPTOP-AKHDRHHE:~/helloworld$ make
gcc -c hello.c -o hello.o
gcc -c main.c -o main.o
gcc -o main hello.o main.o

执行make命令之后,会把Makefile文件命令从下往上执行

clean命令的使用:

clean使用格式如下:

# Makefile的内容通常由以下3部分组成
# <目标名称>:<前置依赖>
# <TAB键><需要执行的命令># 放在第一个的是默认目标
# 目标是编译出main文件,依赖hello.o和main.o
# 编译的命令是gcc -o main hello.o main.o
main:hello.o main.ogcc hello.o main.o -o main# 目标是编译出main.o文件,依赖main.c
# 编译的命令是gcc -c main.c -o main.o/或gcc -c main.c 它会自动识别到名字并转换成main.o
main.o:main.cgcc -c main.c -o main.o# 目标是编译出hello.o文件,依赖hello.c
# 编译的命令是gcc -c hello.c -o hello.o/或gcc -c hello.c 它会自动识别到名字并转换成hello.o
hello.o:hello.cgcc -c hello.c -o hello.o
# 清除不需要的文件
clean:rm main.o hello.o

使用方法:

itcai@LAPTOP-AKHDRHHE:~/helloworld$ make clean
rm main.o hello.o

Makefile_引入变量

格式如下:

# Makefile的内容通常由以下3部分组成
# <目标名称>:<前置依赖>
# <TAB键><需要执行的命令># 定义变量 itcai
# 变量的值是 main.o hello.o 定义也可写为itcai := main.o hello.o
# 也可以写成多行的形式,在每一行的结尾加上反斜杠\
# 反斜杠\表示当前行未结束,下一行是当前行的延续
# 变量的引用方式是$(itcai)
itcai := main.o\hello.o# 放在第一个的是默认目标
# 目标是编译出main文件,依赖$(itcai)
# 编译的命令是gcc  $(itcai) -o main
main:$(itcai)gcc  $(itcai) -o main# 目标是编译出main.o文件,依赖main.c
# 编译的命令是gcc -c main.c -o main.o/或gcc -c main.c 它会自动识别到名字并转换成main.o
main.o:main.cgcc -c main.c -o main.o# 目标是编译出hello.o文件,依赖hello.c
# 编译的命令是gcc -c hello.c -o hello.o/或gcc -c hello.c 它会自动识别到名字并转换成hello.o
hello.o:hello.cgcc -c hello.c -o hello.o
# 清除不需要的文件
clean:rm $(itcai)

Makefile_自动推导

# 告诉 make:最终目标是 main,不能省略
main : main.o hello.o# 下面什么都不用写,make 会:
# 1) 自动推导 main.o <- main.c
# 2) 自动推导 hello.o   <- hello.c
# 3) 自动链接 main <- main.o hello.o
#    故可省略

但其自动推导不出hello.h,故,hello.h仍需显式标明依赖,否则.h文件发生变化make不会察觉

可改为如下版本:

# Makefile的内容通常由以下3部分组成
# <目标名称>:<前置依赖>
# <TAB键><需要执行的命令># 定义变量 itcai
# 变量的值是 main.o hello.o 定义也可写为itcai := main.o hello.o
# 也可以写成多行的形式,在每一行的结尾加上反斜杠\
# 反斜杠\表示当前行未结束,下一行是当前行的延续
# 变量的引用方式是$(itcai)
itcai := main.o\hello.o# 放在第一个的是默认目标
# 目标是编译出main文件,依赖$(itcai)
# 编译的命令是gcc  $(itcai) -o main
main:$(itcai)gcc  $(itcai) -o main# 目标是编译出main.o文件,依赖hello.h,其他的依赖文件它会自动推导
main.o:hello.h# 目标是编译出hello.o文件,依赖hello.h,其他的依赖文件它会自动推导
hello.o:hello.h# 清除不需要的文件
clean:rm $(itcai)

Makefile_伪目标

作用: 防止目标名与同名文件冲突,并告诉 make“无论文件是否存在,每次都要执行”

# 声明伪目标 clean
.PHONY:cleanclean:rm main.o hello.o

若不显式声明伪目标,当所在路径中有与伪目标同名的文件时,伪目标命令就不会执行

.PHONY: clean 告诉 make:
“clean 不是一个文件名,请每次都执行它下面的命令。”

.PHONY 不是必须,但强烈推荐:防止文件夹里恰好出现同名文件导致规则失效

伪目标可以自定义
# 自定义伪目标
.PHONY: clean run qemu gdbclean:@echo "删除中间文件..."rm -f *.o *.korun:qemu-system-x86_64 -enable-kvm -m 2G -kernel mykernel.elfgdb:qemu-system-x86_64 -s -S -kernel mykernel.elf &gdb vmlinux -ex "target remote :1234"

名称随意clean、run、qemu、gdb 都可以,完全自定义

Makefile_忽略错误

当连续执行同一条命令时,因为命令已经执行过一次且所操作文件没有改变,所以会报错

itcai@LAPTOP-AKHDRHHE:~/helloworld$ make clean
rm main.o hello.o
itcai@LAPTOP-AKHDRHHE:~/helloworld$ make clean
rm main.o hello.o
rm: cannot remove 'main.o': No such file or directory
rm: cannot remove 'hello.o': No such file or directory
make: *** [Makefile:22: clean] Error 1

可通过在要忽略此类错误的命令前加 - 来忽略该错误
如:

# 声明伪目标 clean
.PHONY:cleanclean:-rm main.o hello.o

再次连续执行该命令,结果如下:

itcai@LAPTOP-AKHDRHHE:~/helloworld$ make clean
rm main.o hello.o
itcai@LAPTOP-AKHDRHHE:~/helloworld$ make clean
rm main.o hello.o
rm: cannot remove 'main.o': No such file or directory
rm: cannot remove 'hello.o': No such file or directory
make: *** [Makefile:22: clean] Error 1
itcai@LAPTOP-AKHDRHHE:~/helloworld$ make clean
rm main.o hello.o
rm: cannot remove 'main.o': No such file or directory
rm: cannot remove 'hello.o': No such file or directory
make: [Makefile:24: clean] Error 1 (ignored)

在报错后会显示(已忽略)

Makefile_名称对应

目标名称必须和gcc命令生成的目标文件同名,即名称对应

若不对应,如下所示:

# Makefile的内容通常由以下3部分组成
# <目标名称>:<前置依赖>
# <TAB键><需要执行的命令># 放在第一个的是默认目标
# 目标是编译出main文件,依赖hello.o和main.o
# 编译的命令是gcc  hello.o main.o -o main123
main:hello.o main.ogcc hello.o main.o -o main123

则连续执行同一条命令而不会报错

itcai@LAPTOP-AKHDRHHE:~/helloworld$ make
cc    -c -o hello.o hello.c
cc    -c -o main.o main.c
gcc hello.o main.o -o main123
itcai@LAPTOP-AKHDRHHE:~/helloworld$ make
gcc hello.o main.o -o main123
itcai@LAPTOP-AKHDRHHE:~/helloworld$ make
gcc hello.o main.o -o main123

原因:目标名称是追踪监控的目标,而gcc命令的生成目标是所生成文件的名字,当追踪不到追踪监控的目标时会一直执行后续的gcc命令
fopen_test: fopen_test.c

# 定义变量CC为gcc
CC := gcc
# $@ 指目标文件
# $^ 指依赖文件
# gcc -o fopen_test fopen_test.c-$(CC) -o $@ $^  
#./fopen_test-./$@
#rm ./fopen_test-rm ./$@
http://www.dtcms.com/a/356088.html

相关文章:

  • 进程组 会话 作业控制 守护进程
  • LeetCode 100 -- Day7
  • JDK8升级到JDK17的注意事项
  • @RequiredArgsConstructor 和构造同时使用,注入会不会导致空指针
  • Dify 中的 Signal Killed 问题排查指南
  • 强化学习入门专栏目录
  • 2002-2020年全国投入产出表数据
  • 【C++八股文】操作系统篇
  • C语言 部分内存相关的库函数
  • 广东省省考备考(第八十九天8.28)——判断推理(听课后强化训练)
  • 事务的五大状态
  • QT LInux 开发中一些常用的方法
  • CVPR小模型创新点深度分析:小VLM化身精准向导,大模型多模态推理效率全面加速,性能突破不再依赖算力堆叠
  • 8.28作业
  • Android 编写高斯模糊功能
  • Github上传READ.md后出现不识别换行符的问题
  • Shell编程入门到实战:从基础语法到自动化脚本
  • 网络是怎样连接的,笔记整理
  • C语言知识点补充(链表和队列)
  • 8.变量和数据类型
  • 浏览器访问 ASP.NET Core wwwroot 目录下静态资源的底层实现
  • 多线程 线程池 并发
  • 机器视觉学习-day08-图像缩放
  • MBA/EMBA毕业论文写作总结
  • 第20章|轻松实现远程控制
  • NumPy 2.x 完全指南【三十二】通用函数(ufunc)之数学运算函数
  • 面试tips--JVM(1)--对象分配内存的方式TLAB
  • CTFshow系列——命令执行web61-68
  • C++之多态篇
  • 君正T31学习(四)- MT7682+VLC出图