Linux 开发工具(四) 熟悉自动化构建 make/Makefile

发布时间:2026/10/19 7:20:23

Linux 开发工具(四) 熟悉自动化构建 make/Makefile 目录一. make/makefile 的概念1.1 Makefile的基本语法1.2 代码示例二. make/makefile 的使用2.1 文件的清理2.2 make 的使用细节2.2.1 make/make【目标名】2.2.2 make 的执行规则2.2.2.1 stat2.3 makefile 的使用细节2.3.1 .PHONY2.3.2 makefile 的依赖关系推导三. make/makefile的进阶使用3.1 变量的定义和使用3.1.1 变量实现代码的编译3.1.2 特殊变量 $ $^3.2 多文件情况3.2.1 版本13.2.2 版本2一. make/makefile 的概念make是 Linux 中的一个自动化构建工具主要用于自动执行编译、链接等操作。你可以把它理解为帮我们自动调用 gcc/g不用每次手动输入一大堆编译命令。makefile是一个描述构建规则的文件告诉 make哪些文件需要生成生成文件需要依赖哪些文件应该执行什么命令。1.1 Makefile的基本语法目标文件: 依赖文件1 依赖文件2 ...依赖列表可为空 依赖方法1 依赖方法2 ...myproc: myproc.cpp g myproc.cpp -o myproc myproc → 目标文件最终要生成的文件 myproc.cpp → 依赖文件生成目标所需要的文件 : → 依赖关系表示 myproc 依赖 myproc.cpp g ... → 依赖方法告诉 make 如何生成目标文件1.2 代码示例# 使用相对路径 bin/myproc: src/myproc.cpp mkdir -p bin g -o bin/myproc src/myproc.cpp # 也可以使用绝对路径 # /home/lzx/myproc: /home/lzx/code/myproc.cpp # g -o /home/lzx/myproc /home/lzx/code/myproc.cpp# 默认读取当前目录中的 Makefile make # -f指定 Makefile 文件路径不切换工作目录 make -f /home/lzx/project/Makefile # -C指定工作目录切换目录后执行 make make -C /home/lzx/project # -C 和 -f 组合使用 make -C /home/lzx/project -f Makefile二. make/makefile 的使用2.1 文件的清理当我们完成编译想要清除编译好的可执行文件时可以在makefile输入以下指令2.2 make 的使用细节2.2.1 make/make【目标名】make默认选择 Makefile 中的第一个目标进行构建但我们也可以通过make【目标名】指定其他目标。#Makefile myproc: myproc.cpp g myproc.cpp -o myproc test: test.cpp g test.cpp -o test hello: hello.cpp g hello.cpp -o hellomake # 默认构建第一个目标 myproc make test # 指定构建 test make hello # 指定构建 hello2.2.2 make 的执行规则make也并不是一定会对目标进行构建为什么呢因为 make的作用不仅是执行编译命令还会根据目标文件和依赖文件的时间戳判断是否需要重新构建。myproc: myproc.cpp g myproc.cpp -o myproc情况make 的行为myproc不存在执行命令生成目标文件myproc.cpp比myproc更新重新编译更新目标文件myproc已存在且比myproc.cpp更新不重新编译认为目标已经是最新的2.2.2.1 stat我们之前提到 make 会根据目标文件和依赖文件的时间戳来判断是否构建指令stat可以让我们更直观的理解。stat是 Linux 中用于查看文件或目录详细属性信息的命令。时间含义什么情况下会变化Accessatime最近一次访问文件内容的时间读取文件内容时时间可能更新Modifymtime文件内容最后修改的时间修改文件内容时更新Changectime文件状态最后变化的时间修改权限、所有者、硬链接数等信息时更新修改文件内容也会更新Birth文件创建时间表示文件创建的时间前提是文件系统支持记录make 正是基于目标文件、依赖文件的修改时间(Modify)来判断的。2.3 makefile 的使用细节2.3.1 .PHONY.PHONY 用于声明伪目标告诉make这个目标不是一个真正需要生成的文件而是一个需要执行的任务。我们在之前提到了make的执行规则要判断执行文件和目标文件的时间戳而.PHONY 的作用就是告诉 make指定的目标是伪目标不对应一个需要生成的实际文件因此不需要通过检查同名目标文件的时间戳来判断是否执行命令。2.3.2 makefile 的依赖关系推导make从上往下寻找目标的依赖关系找到最底层的依赖后再从下往上依次执行构建命令。#Makefile myproc: myproc.o gcc myproc.o -o myproc myproc.o: myproc.s gcc -c myproc.s -o myproc.o myproc.s: myproc.i gcc -S myproc.i -o myproc.s myproc.i: myproc.c gcc -E myproc.c -o myproc.i① 从上往下查找依赖入栈myproc ↓ myproc.o ↓ myproc.s ↓ myproc.i ↓ myproc.c源文件已存在② 从下往上构建目标出栈gcc -E myproc.c -o myproc.i # 预处理 gcc -S myproc.i -o myproc.s # 编译 gcc -c myproc.s -o myproc.o # 汇编 gcc myproc.o -o myproc # 链接三. make/makefile的进阶使用3.1 变量的定义和使用Makefile 中可以使用定义变量通过$(变量名)引用变量。我们会发现每行命令前面都有符号的作用主要是取消命令的回显如果不加结果如下3.1.1 变量实现代码的编译3.1.2 特殊变量 $ $^$和$^都是Makefile 中的自动变量用于简化构建命令。自动变量含义$当前规则的目标文件$^当前规则的所有依赖文件去重3.2 多文件情况3.2.1 版本1BIN myproc CC g OBJ myproc.o FLAGS -c # 1. 默认目标是 myproc依赖 myproc.o $(BIN): $(OBJ) $(CC) $^ -o $ # 2. % 是模式匹配符用于匹配文件名中的相同部分 # 例如make 需要生成 myproc.o # %.o → myproc.o此时 % 匹配到 myproc # %.cpp → myproc.cpp将 myproc 代入依赖文件名 # 因此推导出myproc.o 依赖 myproc.cpp %.o: %.cpp $(CC) $(FLAGS) $ -o $ # 3. $ 是自动变量表示当前规则的第一个依赖文件 # 这里 $ → myproc.cpp # 而 $ → myproc.o表示当前目标文件 # 所以上面的命令展开后为 # g -c myproc.cpp -o myproc.o%模式匹配符根据目标文件名匹配相同部分推导出依赖文件名。$自动变量表示当前规则的第一个依赖文件。$自动变量表示当前规则的目标文件。3.2.2 版本2# 1. 定义变量 BIN myproc # 最终生成的可执行文件 CC g # 编译器 SRC $(shell ls *.cpp) # 获取当前目录下所有 .cpp 文件 # SRC $(wildcard *.cpp) # 另一种写法更推荐 OBJ $(SRC:.cpp.o) # 将所有 .cpp 后缀替换为 .o LFLAGS -o # 指定输出文件名 FLAGS -c # 只编译生成 .o不链接 RM rm -f # 删除命令 # 2. 定义最终目标及其依赖关系 # $(BIN) → myproc # $(OBJ) → main.o add.o sub.o假设存在这三个源文件 # 表示 myproc 依赖这些 .o 文件 $(BIN): $(OBJ) $(CC) $^ $(LFLAGS) $ echo linking... $^ to $ # $^ → 所有依赖文件即 main.o add.o sub.o # $ → 当前目标文件即 myproc # 实际执行g main.o add.o sub.o -o myproc # 3. 定义模式规则分别生成 .o 文件 # % 是模式匹配符 # 需要生成 main.o 时% 匹配 main推导出 main.cpp # 需要生成 add.o 时% 匹配 add推导出 add.cpp # 每次匹配都对应一条独立的编译规则 %.o: %.cpp $(CC) $(FLAGS) $ echo compiling... $ to $ # $ → 当前规则的第一个依赖文件例如 main.cpp # $ → 当前规则的目标文件例如 main.o # 实际执行g -c main.cpp # 默认生成 main.o # 表示不回显命令本身1.$( )引用变量或调用函数引用变量$(CC)获取变量CC的值。调用函数例如$(wildcard *.cpp)。示例CC g那么$(CC)就会展开为g。2.wildcard使用 Makefile 自带的功能查找文件示例SRC $(wildcard *.cpp)。*.cpp表示匹配所有以.cpp结尾的文件。查找结果会赋值给变量SRC。按照make的工作目录查找而不是 Makefile 所在的目录。3.shell执行 Shell 命令并获取输出示例SRC $(shell ls *.cpp)。$(shell ...)会执行括号中的 Shell 命令并获取其标准输出。ls *.cpp用于列出匹配的.cpp文件结果赋值给SRC。同样以make的工作目录为基
延伸阅读

更多相关文章

2026/10/19 7:20:23

真机实验知识点汇总

IPIP网络位主机位网络位---IP所在的网段(广播域)主机位---主机编号同一个广播域,使用相同的网络位,不同的主机位的IP地址不同广播域中,使用网络位不同的IP地址掩码32位二进制,连续的1和连续的0组成掩码和IP…

2026/10/19 7:15:23

自托管手工创作项目管理工具artcraft:从问题到部署的完整复盘

做手工这事儿,最磨人的往往不是手艺本身,而是“创作过程的管理”。灵感记在手机备忘录里,下次找要翻半天;材料买了一堆,真要用的时候死活想不起来放在哪;做到一半的作品拍了几张照片,过两个星期…

2026/10/19 8:45:45

开源CLI代码审查工具:Git原生+LLM可插拔的自动化守门人

1. 项目概述:这不是又一个“AI写代码”玩具,而是一套可嵌入日常开发流的开源代码审查协作者open-code-review 这个名字乍看平平无奇,但拆开来看——open(开放)、code(代码)、review(…

2026/10/19 8:45:45

open-code-review:一种开放、协议化的代码评审接口标准

1. “open-code-review”不是工具名,而是一类新型代码评审范式的命名起点最近在几个技术社区和内部工程效能群里,频繁看到“open-code-review”这个写法——它既不像传统工具名(比如 SonarQube、Reviewable),也不像标准…

2026/10/19 8:45:45

数据类型深度解析:从内存布局到类型转换的实战避坑指南

接手过不少线上故障,最后翻来覆去查根因,十有八九都会落回到一个最基础的概念上:数据类型。索引建错、接口传参对不上、数据库存储精度丢失、某个字段在序列化之后悄悄变了样——追到源头,全是类型处理不当惹的祸。这篇就围绕“4.…

2026/10/19 8:45:44

纯C++无迹卡尔曼滤波UKF实现:多传感器融合与姿态估计实战

简介:这份资源面向学习卡尔曼滤波与自动驾驶定位算法的C开发者,聚焦CTRV运动学模型下的无迹卡尔曼滤波(UKF)实现,解决非线性系统状态估计中EKF线性化误差偏大的问题。压缩包共404个文件,约3.05MB&#xff0…

2026/10/19 8:45:44

ZXing二维码扫描解码链路与识别率优化实战

简介:这份资源是面向Android及移动端开发者的ZXing二维码扫描集成示例工程,适合需要为应用快速添加扫码能力的初中级开发者。ZXing作为开源跨平台条码库,支持QR码、Data Matrix、Aztec、PDF417及Code 39、Code 128等多种码制,可实…

2026/10/19 8:40:42

open-code-review:基于CLI与Git集成的LLM代码审查实践

1. 这不是又一个“AI代码审查”玩具:open-code-review 的真实定位与设计哲学open-code-review 这个名字乍看平平无奇,甚至有点“开源即正义”的朴素感——但如果你把它和 codex cli、zcode cli、trae cli 这些近期高频出现的工具放在一起对比&#xff0c…

2026/10/18 0:01:50

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/19 0:04:56

悟空开源无代码平台实战:从实体建模到应用设计避坑指南

简介:基于悟空开源无代码平台的多种应用设计源码,面向希望在不编写代码的情况下快速搭建CRM、HRM、财务系统、ERP、SRM等业务应用的企业与技术人员,通过拖放式界面和内置模板即可完成应用定制与部署。压缩包共697个文件,约10.74MB…

2026/10/19 0:04:56

基于.NET9的多租户权限系统:数据权限与动态API落地实践

简介:这份资源是一套面向 .NET 与 Vue 全栈开发者的中台权限管理系统,后端基于 .Net9,前端采用 Vue3 Element Plus,并配套 uniapp uviewui 移动端方案,实现前后端分离。系统覆盖多租户隔离、数据权限、动态 Api、任务…

2026/10/19 0:04:56

场地预约小程序毕设实战:SSM+微信小程序+MySQL数据库设计到避坑

简介:面向毕业设计场景的场地预约小程序完整项目,基于微信小程序SSMMySql技术栈开发,适合计算机相关专业学生作为选题参考、功能扩展或二次开发起点。系统实现场地类型管理、场地管理、预约管理、取消申请与押金退回等功能,分为管…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑