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

深入掌握 Makefile 与 Make 工具:高效管理自动化编译的核心原理和最佳实践


✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭
~✨✨

🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。

我是Srlua小谢,在这里我会分享我的知识和经验。🎥

希望在这里,我们能一起探索IT世界的奥妙,提升我们的技能。🔮

记得先点赞👍后阅读哦~ 👏👏

📘📚 所属专栏:Linux

欢迎访问我的主页:Srlua小谢 获取更多信息和资源。✨✨🌙🌙

​​

​​

目录

make与makefile

基本概念

Makefile 结构

解释

常用命令

make 的优点

.PHONY

为什么使用 .PHONY

.PHONY 保证目标总是执行

特殊符号

使用 % 的模式规则

解释

例子

常用的自动化变量

优势

是否需要重新编译源文件或可执行程序

1. 源文件的修改

2. 依赖关系

3. 可执行程序的时间戳

4. 手动触发

5. Makefile 中的配置

总结

理解一下makefile/make基本原理


make与makefile

make 是一个在 Unix/Linux 系统中广泛使用的构建工具,用于自动化编译和构建项目。make 命令通过读取一个名为 Makefilemakefile 的文件,根据其中定义的规则执行各种任务(如编译、链接等),从而简化和自动化项目的构建过程。

一句话理解本质:

make就是一个命令
makefile就是一个文件

基本概念

  1. 目标 (Target)make 要生成的文件或要执行的动作。
  2. 依赖项 (Dependencies):生成目标所依赖的文件或目标。
  3. 命令 (Commands):生成目标所需的命令。每个命令行通常以制表符(Tab)开始。
  4. 变量makefile 中定义的变量,允许复用和动态设置。

Makefile 结构

典型的 makefile 文件结构如下:

# 定义变量
CC = gcc
CFLAGS = -Wall -g

# 目标规则
# 语法:target: dependencies
#      command
program: main.o utils.o
	$(CC) $(CFLAGS) -o program main.o utils.o

# 生成目标文件的规则
main.o: main.c
	$(CC) $(CFLAGS) -c main.c

utils.o: utils.c
	$(CC) $(CFLAGS) -c utils.c

# 清理命令
clean:
	rm -f *.o program

解释

  • 变量CC 表示编译器(这里是 gcc),CFLAGS 是编译标志。
    .PHONY: clean
    
    clean:
    	rm -f *.o program
    

  • 目标 program:依赖 main.outils.o,通过 gcc -Wall -g -o program main.o utils.o 来生成最终可执行文件 program
  • 文件依赖main.o 依赖 main.c,而 utils.o 依赖 utils.c。每个 .o 文件都通过相应的 gcc 命令编译。
  • 清理目标clean 是一个伪目标,用于清理生成的文件。

常用命令

  • make:使用默认目标(Makefile 中第一个定义的目标)进行构建。
  • make clean:调用 clean 目标,用于删除编译生成的文件。
  • make <target>:指定目标进行构建,例如 make program

make 的优点

  1. 自动化构建:根据文件依赖关系,只重新编译必要的文件。
  2. 易于维护:通过 makefile 管理复杂项目的构建流程。

.PHONY

makefile 中,.PHONY 用于声明「伪目标」(phony targets),即不直接对应文件的目标。这些目标通常是一些执行操作的命令,而非生成文件。例如,cleanallinstall 等都是常见的伪目标。.PHONY 告诉 make,即使存在与这些目标名称相同的文件,也不要将其视为文件,而是直接执行相应命令。

为什么使用 .PHONY

.PHONY 可以避免文件名和目标名冲突的问题。例如,如果你的项目目录下有一个文件名叫 clean,当你执行 make clean 时,make 会认为目标已经完成,不会执行 clean 目标中的命令。而加上 .PHONY 后,make 会忽略同名文件,直接执行伪目标。

例如:

.PHONY: clean

clean:
	rm -f *.o program

在这个例子中:

  • 即使目录中有一个名为 clean 的文件,make clean 仍会忽略它,并执行删除操作。
  • 这是因为 .PHONY 告诉 makeclean 是个伪目标,不对应于一个文件。

.PHONY 保证目标总是执行

当目标被声明为 .PHONY 后,每次调用它时,make 不会检查其是否已经完成,而是始终执行目标的命令,这对一些清理、测试或其他重复操作特别有用。

特殊符号

makefile 中,% 是通配符,常用于模式规则(Pattern Rules),用于匹配文件名的通用模式。模式规则让 make 能够定义一类目标的构建方式,而无需为每个目标单独编写规则。例如,可以用 %.o: %.c 来描述如何从 .c 文件生成 .o 文件,% 表示文件名的任意部分。

使用 % 的模式规则

以下是模式规则的典型结构:

%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@
解释
  • %.o: %.c 表示所有 .o 文件都可以通过对应的 .c 文件生成。
  • $<make 的自动化变量,代表第一个依赖文件,在这里是 .c 文件。
  • $@ 是目标文件(在这里是 .o 文件)的名称。

这样,不需要为每个 .c 文件写一条规则。例如,foo.c 会自动生成 foo.obar.c 会自动生成 bar.o

例子

一个更完整的 makefile 例子:

CC = gcc
CFLAGS = -Wall -g

# 默认目标
all: program

# 模式规则
%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

# 链接
program: main.o utils.o
	$(CC) $(CFLAGS) -o program main.o utils.o

clean:
	rm -f *.o program

常用的自动化变量

  • $@:表示目标文件。
  • $<:表示第一个依赖文件。
  • $^:表示所有依赖文件列表。

优势

使用 % 可以大大简化 makefile,特别是当项目中有很多类似的文件需要相同的规则时,减少了重复代码,使 makefile 更加简洁和通用。

是否需要重新编译源文件或可执行程序

在使用 makemakefile 进行项目管理时,决定是否需要重新编译源文件或可执行程序通常取决于以下几个因素:

1. 源文件的修改

  • 重新编译:当源文件(如 .c.cpp 文件)发生变化时,make 会检测到这些变化,并重新编译受影响的文件。
  • 不需要重新编译:如果源文件未发生变化,make 会认为相应的目标(如 .o 文件或可执行程序)是最新的,因此不会重新编译。

2. 依赖关系

make 会跟踪文件的依赖关系。每个目标都有其依赖项,make 会检查依赖项的时间戳:

  • 依赖项变化:如果目标依赖的文件(例如头文件)发生变化,且这些变化可能影响目标的生成,make 将重新编译相关的源文件。
  • 无依赖项变化:如果所有依赖项均未变化,make 将跳过编译步骤。

3. 可执行程序的时间戳

  • 重新生成:如果可执行程序的源文件(或任何依赖项)被修改,make 会重新编译并链接生成新的可执行文件。
  • 无需更新:如果可执行程序已经存在,且所有依赖项都未被修改,则 make 会认为可执行程序是最新的,跳过编译过程。

4. 手动触发

有时可能需要强制重新编译,即使文件没有变化,这可以通过以下方式实现:

  • make clean:运行一个清理目标,删除所有中间文件和可执行程序,然后执行 make 重新构建整个项目。
  • 使用 make 的选项:例如,使用 make -Bmake --always-make 可以强制 make 重新编译所有目标。

5. Makefile 中的配置

有时在 makefile 中的配置也会影响重新编译的条件,例如使用变量、条件语句和模式规则等。

总结

  • 需要重新编译:当源文件、依赖文件发生变化,或者手动强制重新编译时。
  • 不需要重新编译:当源文件和依赖文件均未发生变化,且可执行程序是最新的。

通过这些机制,make 能够有效地管理项目构建过程,避免不必要的重复编译,从而节省时间和资源。

理解一下makefile/make基本原理

1.makefile文件,会被make从上到下开始扫描,第一个目标名,是缺省要形成的。如果我们想执行其他组的依赖关系和依赖方法,make name

2.make makfile在执行gcc命令的时候,如果发生了语法错误,就会终止推导过程

3.make解释makefie的时候,是会自动推导的。一直推导,推导过程,不执行依赖方法。直到推导到有依赖文件存在,然后在逆向的执行所有的依赖方法

4.make默认只形成一个可执行程序

​​

希望对你有帮助!加油!

若您认为本文内容有益,请不吝赐予赞同并订阅,以便持续接收有价值的信息。衷心感谢您的关注和支持!


http://www.kler.cn/a/376132.html

相关文章:

  • 数据治理,数据提取,大数据中心建设,大数据治理总体解决方案书(word,ppt原件)
  • 前端react常见面试题目(basic)
  • Logback 常用配置详解
  • 从零开始构建 ChatGPT
  • 任何python安装gdal出现的问题
  • 【 纷享销客-注册安全分析报告-无验证方式导致安全隐患】
  • 关于数学建模的一些介绍
  • 【C++篇】数据之林:解读二叉搜索树的优雅结构与运算哲学
  • CSS、Less、Scss
  • 介绍Illustrator软件的“编组选择工具”。
  • 现代化水电管理:Spring Boot在大学城的实践
  • 【NPM】工程化依赖包/库开发 之 基础知识2
  • Web安全: OWASP_TOP_10 原理|危害|绕过技术|修复建议.
  • 本地可以插入表记录,生产不能插入表记录
  • 基于springboot+vue实现的公考知识学习平台 (源码+L文+ppt)4-103
  • 【flutter列表播放器】
  • 基于Spring Boot的网络考试系统设计与实现(源码+定制+开发)网络考试管理平台、智能考试评估系统、题库管理系统设计、Spring Boot考试平台开发
  • 数字IC后端实现之Innovus Place跑完density爆涨案例分析
  • stable diffusion webui API调用示例,调用参数,override_settings参数
  • 时光书屋--
  • 标签之文字排版,图片,链接,音视频(HTML) 基础版
  • 4、liunx开机启动详解
  • 信息学科平台设计与实现:Spring Boot技术详解
  • 【Android】常见问题集锦
  • 112. gui辅助调节光源阴影
  • 浅谈鸿蒙生态崛起的机遇