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

Linux中的`make`与`Makefile`:项目自动化构建工具

Linux中的makeMakefile:项目自动化构建工具

在Linux及类Unix系统中,make是一种广泛使用的自动化构建工具,它通过读取和执行Makefile(或makefile,文件名不区分大小写)中的指令来自动化编译和构建程序。Makefile定义了构建过程中需要执行的命令、依赖关系以及构建目标,极大地简化了复杂项目的构建过程。本文将深入探讨make命令、Makefile的编写规则、常用函数以及高级特性,帮助读者更好地理解和使用这一强大的工具。

一、make命令简介

make命令是一个根据Makefile中的指令来自动编译和链接程序的工具。它首先会检查所有需要编译的源文件以及它们所依赖的库或文件是否是最新的,如果不是,则根据Makefile中的规则重新编译这些文件。这种方式避免了不必要的编译,提高了构建效率。

二、Makefile的基本结构

Makefile由一系列规则(rules)组成,每个规则定义了如何生成一个或多个目标文件(target)。规则的基本格式如下:

target: dependenciescommand...
  • target:规则的目标,通常是文件名,也可以是一个伪目标(如clean)。
  • dependencies:目标的依赖文件列表,用于判断目标是否需要重新构建。如果依赖文件比目标文件新,或者目标文件不存在,则执行命令。
  • command:当目标需要被构建时执行的命令。每个命令前必须有一个制表符(Tab),而不是空格。
三、Makefile的编写规则
1. 变量

Makefile中可以使用变量来存储文件名、编译选项等,以便在多处重复使用。变量定义和引用的方式如下:

CC=gcc
CFLAGS=-Wall -ghello: hello.o$(CC) $(CFLAGS) -o hello hello.ohello.o: hello.c$(CC) $(CFLAGS) -c hello.c
2. 自动变量

make还定义了一系列自动变量,用于在规则中代表文件名、依赖列表等。常用的自动变量包括$@(代表目标文件名)、$<(代表第一个依赖文件名)、$^(代表所有依赖文件名)等。

3. 伪目标

伪目标不是文件名,而是一个标签,用于执行一些特定的操作,如清理构建文件。伪目标后面通常使用.PHONY来声明,以避免与同名文件冲突。

.PHONY: cleanclean:rm -f *.o hello
4. 模式规则

模式规则允许为符合特定模式的文件定义构建规则,而不需要为每个文件单独编写规则。模式规则使用%作为通配符。

%.o: %.c$(CC) $(CFLAGS) -c $< -o $@
四、Makefile的常用函数

Makefile支持多种内置函数,用于字符串处理、文件名操作、条件判断等。

  • wildcard:用于查找符合特定模式的文件名列表。
  • patsubst:用于模式替换,将符合模式的字符串替换为另一个字符串。
  • ififeqifneqifdefifndef:用于条件判断。
五、高级特性
1. 递归make

在大型项目中,可能会将项目拆分成多个子项目,每个子项目都有自己的Makefile。此时,可以在顶层Makefile中调用子项目的Makefile,实现递归构建。

subdir:cd subdir && $(MAKE)
2. 静态模式规则

静态模式规则是模式规则的一种扩展,它允许更精确地指定目标和依赖的模式。

objects = foo.o bar.oall: $(objects)$(objects): %.o: %.c$(CC) -c $(CFLAGS) $< -o $@
3. 变量覆盖

在命令行中可以通过-e选项或直接在命令行中指定变量值来覆盖Makefile中的变量值。

make CC=clang
4. 隐式规则

make内置了许多隐式规则,用于编译和链接C、C++等语言的源文件。当Makefile中没有为特定目标定义规则时,make会尝试使用隐式规则来构建目标。

六、实践案例

假设我们有一个简单的C语言项目,包含main.cutils.cutils.h三个文件,我们希望使用makeMakefile来自动化编译和构建这个项目。下面是一个可能的Makefile示例:

# 定义编译器和编译选项
CC=gcc
CFLAGS=-Wall -g# 定义项目中的源文件和目标文件
SRCS=main.c utils.c
OBJS=$(SRCS:.c=.o)
TARGET=myapp# 默认目标,即当不指定目标时执行的操作
all: $(TARGET)# 链接目标文件生成可执行文件
$(TARGET): $(OBJS)$(CC) $(CFLAGS) -o $@ $^# 编译C源文件生成目标文件
%.o: %.c$(CC) $(CFLAGS) -c $< -o $@# 伪目标,用于清理构建过程中生成的文件
.PHONY: cleanclean:rm -f $(OBJS) $(TARGET)# 依赖关系(如果项目中有头文件,则不需要显式写出,但保持其最新状态很重要)
# 注意:这里不直接写出头文件依赖,因为make会基于时间戳自动检查
# 但对于复杂的项目,可能需要使用-MM等gcc选项生成依赖关系# 如果需要自动处理头文件依赖,可以在Makefile中加入如下规则(示例)
# 注意:这里只是一个简单的示例,实际项目中可能需要更复杂的逻辑
%.d: %.c@set -e; rm -f $@; \$(CC) -MM $(CFLAGS) $< > $@.$$$$; \sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \rm -f $@.$$$$# 引入所有.d文件(如果存在),这些文件包含了文件的依赖关系
-include $(SRCS:.c=.d)

然而,上面的%.d规则及其sed命令是处理头文件依赖的一种较为复杂的方式,主要用于生成.d文件,这些文件包含了源文件和目标文件以及它们所依赖的头文件的列表。在上面的示例中,如果源文件更改或依赖的头文件更改,则.d文件也会更新,并且make会基于这些更新来重新编译相应的源文件。

但是,对于简单的项目或刚开始使用make的用户来说,可能不希望一开始就引入这么复杂的逻辑。在实际应用中,可以根据项目的复杂度和需求来选择是否自动生成依赖关系。

对于上面的简单项目,如果头文件(如utils.h)更改,用户通常需要手动触发重新编译。但在更复杂的项目中,使用自动生成依赖关系的方法可以极大地简化构建过程,并减少因忘记更新依赖关系而导致的编译错误。

七、总结

makeMakefile是Linux及类Unix系统中不可或缺的项目自动化构建工具。通过编写Makefile,开发者可以定义项目的构建规则、依赖关系以及编译选项,从而实现高效的自动化构建。本文介绍了make命令的基本用法、Makefile的编写规则、常用函数以及高级特性,并给出了一个简单项目的Makefile示例。希望这些内容能够帮助读者更好地理解和使用makeMakefile,提高项目构建的效率和质量。

相关文章:

Linux中的`make`与`Makefile`:项目自动化构建工具

Linux中的make与Makefile&#xff1a;项目自动化构建工具 在Linux及类Unix系统中&#xff0c;make是一种广泛使用的自动化构建工具&#xff0c;它通过读取和执行Makefile&#xff08;或makefile&#xff0c;文件名不区分大小写&#xff09;中的指令来自动化编译和构建程序。Ma…...

GitHub开源项目精选:轻量级预约/预订日历组件,用React和TypeScript构建

在日常开发中&#xff0c;我们经常需要在项目中添加预约或预订功能。今天给大家推荐一个超级轻量级的预约/预订日历组件&#xff0c;它是用React和TypeScript构建的&#xff0c;非常适合那些需要简单易用的日历解决方案的开发者。 安装方法&#xff1a; 你可以选择使用npm或者y…...

闲钱放在哪里?收益稳定且又高!

家庭理财&#xff0c;最大的问题就是&#xff0c;手里这点闲钱&#xff0c;说多不多&#xff0c;但打理起来&#xff0c;还真的很”挠头“。 放银行&#xff0c;存款利率接二连三下调&#xff0c;利息又又又要变少了&#xff01; 投资出去&#xff0c;看着到处的雷声隆隆&…...

【Linux】简易线程池项目

线程池是一个可以巩固一些线程相关接口 && 加强理解的一个小项目。 注意&#xff1a;这里的线程池使用的线程并不是Linux原生接口&#xff0c;而是经过封装的&#xff0c;具体请看线程封装&#xff0c;为什么不使用原生接口&#xff1f; 因为原生接口一旦进行pthread…...

基于vue框架的NBA球星管理系统1878g(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,球员,球员数据,榜单类型,联盟榜单,重要比赛回放,精彩时刻视频,视频专栏,本赛季赛程,十佳球,投票信息,投票结果 开题报告内容 基于Vue框架的NBA球星管理系统 开题报告 一、选题背景 随着互联网的普及和体育产业的蓬勃发展&#x…...

【docker】Dockerfile练习

1、overlay文件系统原理测试 cd /mnt mkdir A B C worker merged echo "From A">./A/a.txt echo "From A">./A/b.txt echo "From A">./A/c.txt echo "From B">./B/a.txt echo "From B">./B/d.txt echo &quo…...

数据可视化的魔法:Python Matplotlib库的奇妙之旅

标题&#xff1a;数据可视化的魔法&#xff1a;Python Matplotlib库的奇妙之旅 在数据科学和分析领域&#xff0c;数据可视化是一种将复杂数据转换为图形表示的强有力工具&#xff0c;它可以帮助我们更直观地理解数据。Python中的Matplotlib库是进行数据可视化的瑞士军刀&…...

Python数据科学的秘密武器:Pandas库的深度解析

标题&#xff1a;Python数据科学的秘密武器&#xff1a;Pandas库的深度解析 Python作为数据科学领域的宠儿&#xff0c;其强大的数据处理能力离不开Pandas库的加持。Pandas是一个开源的数据分析和操作库&#xff0c;它提供了快速、灵活和表达力强的数据结构&#xff0c;旨在使…...

云计算实训24——python基本环境搭建、变量和数据类型、数据集合、py脚本

一、python环境搭建 确保拥有阿里云镜像 查看python环境 [rootpython ~]# yum list installed | grep python 查看epel是否安装 [rootpython ~]# yum list installed | grep epel 安装epel [rootpython ~]# yum -y install epel-release.noarch 查看是否安装python3 [rootpyt…...

深入了解网络性能监控(NPM):优化网络性能的关键

目录 网络性能监控&#xff08;NPM&#xff09;是什么&#xff1f; 关键网络性能指标 案例分享&#xff1a;如何利用NPM优化网络性能 实用技巧&#xff1a;如何高效运维你的网络 结论 随着企业依赖于互联网和内部网络进行业务运营&#xff0c;网络的稳定性和性能显得尤为重…...

Vue引入使用iconfont字体图标

由于element-ui或element-plus提供的图标有时候并不能满足日常需求,所以这篇介绍一下前端引入阿里巴巴矢量图标库使用,不止是vue使用,不限于vue2、vue3,html或是其他框架也是同样的道理,只要引入都是同样可以使用的。 1. 首先进入阿里巴巴矢量图标库官网 官网:https://…...

Doc2Vec

Doc2Vec 是一种扩展自 Word2Vec 的算法&#xff0c;它不仅可以生成词向量&#xff0c;还可以生成句子或文档的向量。下面是一个使用 Doc2Vec 比较两个句子的具体过程&#xff1a; 步骤 1: 训练 Doc2Vec 模型 首先&#xff0c;你需要有一个训练好的 Doc2Vec 模型。训练过程大致…...

MES生产过程透明管理,实施掌握生产每个环节

MES&#xff08;制造执行系统&#xff09;生产过程透明管理&#xff0c;旨在通过集成多种技术手段和管理模块&#xff0c;实现对生产过程的实时监控和精准掌握&#xff0c;确保每个生产环节都能被清晰地记录和追踪。以下是对MES生产过程透明管理的详细阐述&#xff1a; 一、MES…...

Java解析压缩包,并根据指定文件夹上传文件

方法 public Multimap<String, String> getCodeBucketMultimap(HttpServletRequest request)throws IOException {MultipartHttpServletRequest multiRequest (MultipartHttpServletRequest) request;// 基于servlet获取文件流List<MultipartFile> multipartFile…...

【HTML】纯前台字符验证码

效果图&#xff1a; 大致思路&#xff1a; 1.在<canvas>画布里写出几个字符&#xff1b; 2.给字符一个随机的角度和颜色&#xff1b; 3.给字符上画出一些干扰线和干扰点。 <canvas width"100" height"30" id"canvasRef" click"…...

如何在 Vue.js 项目中动态设置页面标题

目录 方法 1:使用 Vue Router 的元信息(meta) 步骤 1: 配置路由元信息 步骤 2: 使用路由守卫设置标题 方法 2:在组件内设置标题 在组件挂载时设置标题 使用响应式数据动态更新标题 在开发 Vue.js 应用时,设置动态页面标题是常见需求,尤其当应用包含多个页面时,为每…...

Eval绕过限制参数限制

PHP Eval函数参数限制在16个字符 PHP代码 <?php$param $_REQUEST[param]; if (strlen($param) < 17 && stripos($param, eval) false && stripos($param, assert) false){eval($param);}?># 部署环境属于ubuntu系统 通过GET传参绕过 由于是…...

计算机网络408考研 2021

2021 计算机网络408考研2021年真题解析_哔哩哔哩_bilibili 1 1 11 1 1 11...

element table表格树形数据展示

element table表格树形数据展示 1、效果 2、代码 <el-table ref"pointMultipleTable" border class"table-box" :data"[damActiveObj]"row-key"id" :tree-props"{ children: children }" :expand-row-keys"expand…...

Ubuntu 安装 Snipaste

一、下载 Snipaste 下载Snipastehttps://zh.snipaste.com/ 二、在/opt 创建 Snipaste 目录&#xff0c;创建 bin 和 icon 子目录&#xff0c;将 Snipaste.AppImage 移动到 bin 目录 三、创建快捷键图标 1. 创建桌面图标&#xff0c;右键→允许运行 yammiemy-pc >/home/y…...

WuliArt Qwen-Image Turbo优化指南:启用BF16模式,让生成更稳定高效

WuliArt Qwen-Image Turbo优化指南&#xff1a;启用BF16模式&#xff0c;让生成更稳定高效 1. 理解BF16模式的核心价值 在个人GPU上运行文生图模型时&#xff0c;最令人沮丧的体验莫过于等待几秒后只得到一张全黑的图片。这不是你的Prompt写得不好&#xff0c;而是FP16&#…...

Navicat连接PostgreSQL常见问题排查指南

1. Navicat连接PostgreSQL的典型问题场景 第一次用Navicat连PostgreSQL的朋友&#xff0c;八成会遇到这个报错画面——输入完账号密码点连接&#xff0c;结果弹个红叉提示"无法连接到服务器"。这种情况我见得太多了&#xff0c;特别是连接远程服务器或者虚拟机里的数…...

[技术突破] 移动高精度定位新纪元:Android平台RTKLIB解决方案全解析

[技术突破] 移动高精度定位新纪元&#xff1a;Android平台RTKLIB解决方案全解析 【免费下载链接】RtkGps Playing with rtklib on android 项目地址: https://gitcode.com/gh_mirrors/rt/RtkGps 技术原理篇&#xff1a;核心算法与协议支持 解锁厘米级定位&#xff1a;R…...

数字电路设计终极指南:用Logisim-Evolution从零搭建你的第一个逻辑系统

数字电路设计终极指南&#xff1a;用Logisim-Evolution从零搭建你的第一个逻辑系统 【免费下载链接】logisim-evolution Digital logic design tool and simulator 项目地址: https://gitcode.com/gh_mirrors/lo/logisim-evolution 数字电路设计与仿真是电子工程和计算机…...

PT站一键转载脚本:100+站点支持,彻底告别手动转载烦恼

PT站一键转载脚本&#xff1a;100站点支持&#xff0c;彻底告别手动转载烦恼 【免费下载链接】auto_feed_js PT站一键转载脚本 项目地址: https://gitcode.com/gh_mirrors/au/auto_feed_js PT&#xff08;Private Tracker&#xff09;社区的资源分享一直是核心文化&…...

广州SEO优化服务有哪些

广州SEO优化服务&#xff1a;全面提升网站排名的关键策略 在当前竞争激烈的互联网环境中&#xff0c;广州SEO优化服务显得尤为重要。搜索引擎优化&#xff08;SEO&#xff09;不仅能够提高网站在搜索结果中的排名&#xff0c;还能有效地吸引更多的潜在客户。广州SEO优化服务有…...

百度网盘直链解析:如何绕过限速实现高速下载的技术方案

百度网盘直链解析&#xff1a;如何绕过限速实现高速下载的技术方案 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 在数字化资源获取过程中&#xff0c;百度网盘作为国内主流云…...

避坑指南:OpenClaw接入百川2-13B-4bits量化模型常见报错大全

避坑指南&#xff1a;OpenClaw接入百川2-13B-4bits量化模型常见报错大全 1. 为什么选择百川2-13B-4bits量化模型 去年我在搭建个人知识管理自动化系统时&#xff0c;第一次尝试将OpenClaw接入本地部署的大模型。当时显存只有12GB的RTX 3060让我在模型选择上捉襟见肘&#xff…...

别只当游戏玩!用《程序员升职记》手把手教你理解CPU指令集和汇编思想

从游戏到芯片&#xff1a;《程序员升职记》中的计算机体系结构启蒙 当你第一次打开《程序员升职记》&#xff08;Human Resource Machine&#xff09;时&#xff0c;可能以为这只是一款画风可爱的解谜游戏。但随着关卡推进&#xff0c;那些看似简单的"收件箱"和"…...

【 MySQL 使用教程】

一、数据操作 数据库 -- 登录 mysql -u root -p -- 查看所有数据库 show databases; -- 创建数据库 create database if not exists 数据库名; -- 删除数据库 drop database if exists 数据库名; -- 进入数据库 use 数据库名;表table -- 查看数据表 show tables;-- 创建表 crea…...