MakeFile使用指南
文章目录
- 1. MakeFile 的作用
- 2. 背景知识说明
- 2.1 程序的编译与链接
- 2.2 常见代码的文档结构
- 3. MakeFile 的内容
- 4. Makefile的基本语法
- 5. 变量定义
- 5.1 一般变量赋值语法
- 5.2 自动化变量
- 6. 通配符
参考:
Makefile教程:Makefile文件编写1天入门
Makefile由浅入深–教程、干货
Makefile详解(超级好) 陈皓
1. MakeFile 的作用
Makefile 文件描述了 Linux 系统下 C/C++ 工程的编译规则,它用来自动化编译 C/C++ 项目。一旦写编写好 Makefile 文件,只需要一个 make 命令,整个工程就开始自动编译,不再需要手动执行 GCC 命令。
2. 背景知识说明
2.1 程序的编译与链接
编译(compile)是将源文件编译成中间目标文件的过程。对于C、C++,在Windows下是.obj
文件,在UNIX下是.o
文件。
链接(link)是将目标文件合成执行文件。
正确的编译要求语法正确,函数与变量的声明正确。一般来说每个源文件(头文件+cpp文件)都对应于一个中间目标文件。 链接是链接函数和全局变量,可以使用中间目标文件来链接。链接时需要支出中间目标文件名称。
在源文件较多的情况下(此时中间目标文件也多),可以给中间目标文件打包,这种包文件就“库文件”(Library FIle),也就是.lib
文件或.a
文件。
2.2 常见代码的文档结构
src
:源码incl
:头文件bin
:执行码lib
:静态/动态库
3. MakeFile 的内容
Makefile 文件中主要包含了五项内容:
- 变量定义:在Makefile 中我们要定义一系列的变量,变量一般都是字符串,这个有点像C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
- 显式规则:显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile 的明显指出,要生成的文件,文件的依赖文件,生成的命令。 .
- 隐晦规则:make有自动推导的功能,隐晦规则指导我们如何简略地书写Makefile的同时又让
make
命令能够顺利执行。 - 文件指示:其包括了三个部分,一个是在一个 Makefile 中引用另一个 Makefile,就像C语言中的 include 一样;另一个是指根据某些情况指定 Makefile 中的有效部分,就像C语言中的预编译 #if 一样;还有就是定义一个多行的命令。
- 注释:Makefile 中只有行注释,和 UNIX 的 Shell 脚本一样,其注释是用“#”字符。
4. Makefile的基本语法
一般的 Makefile 语句的形式如下:
targets:prerequisitescommand
或
targets:prerequisites;commandcommand
其中:
targets
是目标,可以是中间文件,也可以是可执行文件或标签;prerequisites
是依赖的文件,要生成 targets 需要的文件或者是目标。可以是多个,也可以是没有;command
是make 需要执行的命令(任意的 shell 命令)。可以有多条命令,每一条命令占一行。
注意:目标和依赖文件之间要使用冒号分隔开,命令的开始要使用Tab键。
以此规则可以写出如下代码:
test:test.cgcc -o test test.c
上述代码实现的功能就是编译 test.c 文件,通过这个实例可以详细的说明 Makefile 的具体的使用。其中 test 是的目标文件,也是我们的最终生成的可执行文件。依赖文件就是 test.c 源文件,重建目标文件需要执行的操作是gcc -o test test.c
。
5. 变量定义
5.1 一般变量赋值语法
MakeFile中变量定义的基本语法:
valname = valuelist
- MakeFile中的变量没有数据类型(或者理解为是字符数组?)。
- 值列表可以是零项,也可以是一项或者多项。
调用变量的格式:$(valname)
或${valname}
,如
OBJ=main.o test.o test1.o test2.o
test:$(OBJ)gcc -o test $(OBJ)
变量的赋值
Makefile 有四种基本赋值方式:
- 简单赋值 ( := ) 编程语言中常规理解的赋值方式,只对当前语句的变量有效。
- 递归赋值 ( = ) 赋值语句可能影响多个变量,所有目标变量相关的其他变量都受影响(如使用该变量赋值的变量)。
- 条件赋值 ( ?= ) 如果变量未定义,则使用符号中的值定义变量。如果该变量已经赋值,则该赋值语句无效。
- 追加赋值 ( += ) 原变量用空格隔开的方式追加一个新值。
案例:
简单赋值
x:=foo
y:=$(x)b
x:=new
test:@echo "y=>$(y)"@echo "x=>$(x)"
在 shell 命令行执行make test
我们会看到:
y=>foob
x=>new
递归赋值
x=foo
y=$(x)b
x=new
test:@echo "y=>$(y)"@echo "x=>$(x)"
在 shell 命令行执行make test
我们会看到:
y=>newb
x=>new
条件赋值
x:=foo
y:=$(x)b
x?=new
test:@echo "y=>$(y)"@echo "x=>$(x)"
在 shell 命令行执行make test
我们会看到:
y=>foob
x=>foo
追加赋值
x:=foo
y:=$(x)b
x+=$(y)
test:@echo "y=>$(y)"@echo "x=>$(x)"
在 shell 命令行执行make test
我们会看到:
y=>foob
x=>foo foob
5.2 自动化变量
自动化变量是Makefile 自动产生的变量。
自动化变量 | 说明 |
---|---|
$@ | 表示规则的目标文件名。如果目标是一个文档文件(Linux 中,一般成 .a 文件为文档文件,也成为静态的库文件),那么它代表这个文档的文件名。在多目标模式规则中,它代表的是触发规则被执行的文件名。 |
$% | 当目标文件是一个静态库文件时,代表静态库的一个成员名。 |
$< | 规则的第一个依赖的文件名。如果是一个目标文件使用隐含的规则来重建,则它代表由隐含规则加入的第一个依赖文件。 |
$? | 所有比目标文件更新的依赖文件列表,空格分隔。如果目标文件时静态库文件,代表的是库文件(.o 文件)。 |
$^ | 代表的是所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的只能是所有的库成员(.o 文件)名。一个文件可重复的出现在目标的依赖中,变量$^ 只记录它的第一次引用的情况。就是说变量“$^”会去掉重复的依赖文件。 |
$+ | 类似$^ ,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库的交叉引用场合。 |
$* | 在模式规则和静态模式规则中,代表“茎”。“茎”是目标模式中“%”所代表的部分(当文件名中存在目录时,“茎”也包含目录部分)。 |
6. 通配符
通配符 | 使用说明 |
---|---|
* | 匹配0个或者是任意个字符 |
? | 匹配任意一个字符 |
[] | 我们可以指定匹配的字符放在 “[]” 中 |
% | 匹配任意字符 |
通配符可以使用在规则的命令和规则中,但不能直接用于变量声明。如:
# 使用在命令中
.PHONY::clean
clean:rm -rf *.o test
# 使用在规则中
test:*.cgcc -o $@ $^
```我们可以在 Makefile 中这样写
如果我们就是相要通过引用变量的话,我们要使用一个函数 `wildcard`:
```shell
OBJ=$(wildcard *.c)
test:$(OBJ)gcc -o $@ $^
相关文章:
MakeFile使用指南
文章目录 1. MakeFile 的作用2. 背景知识说明2.1 程序的编译与链接2.2 常见代码的文档结构 3. MakeFile 的内容4. Makefile的基本语法5. 变量定义5.1 一般变量赋值语法5.2 自动化变量 6. 通配符 参考: Makefile教程:Makefile文件编写1天入门 Makefile由浅…...

矩阵碰一碰发视频的视频剪辑功能源码搭建,支持OEM
在短视频创作与传播领域,矩阵碰一碰发视频结合视频剪辑功能,为用户带来了高效且富有创意的内容产出方式。这一功能允许用户通过碰一碰 NFC 设备触发视频分享,并在分享前对视频进行个性化剪辑。以下将详细阐述该功能的源码搭建过程。 一、技术…...
VB.NET CRC32 校验
在 VB.NET 中实现 CRC32 校验并在校验失败时退出程序,你可以按照以下步骤进行: 实现 CRC32 计算函数:首先,你需要一个函数来计算给定数据的 CRC32 值。 比较计算的 CRC32 值:然后,你需要将计算出的…...

冒充者综合征上线了
背景 今天干了一件蠢事儿,上周末咸鱼上有人拍了之前发布的一个java程序,基于 JWT 实现的一个五子棋游戏的源代码。想着反正又没事,就找到了移动硬盘拷贝出那个源代码上传网盘发货了。 今天买家找我说解压不了,我电脑解压正常。就…...

【大模型】百度千帆大模型对接LangChain使用详解
目录 一、前言 二、LangChain架构与核心组件 2.1 LangChain 核心架构 2.2 LangChain 核心组件 三、环境准备 3.1 前置准备 3.1.1 创建应用并获取apikey 3.1.2 开通付费功能 3.2 获取LangChain文档 3.3 安装LangChain依赖包 四、百度千帆大模型对接 LangChain 4.1 LL…...
Redis相关面试
以下是一些在面试中关于 Redis 最常被问到的问题,涵盖了 Redis 的基础概念、数据结构、持久化、主从复制、哨兵、集群、应用场景以及常见的缓存问题等。可以根据自身实际项目经验,结合下面的要点进行深入讲解。 1. Redis 基础与特点 Redis 是什么&#x…...

使用强化学习训练神经网络玩俄罗斯方块
一、说明 在 2024 年暑假假期期间,Tim学习并应用了Q-Learning (一种强化学习形式)来训练神经网络玩简化版的俄罗斯方块游戏。在本文中,我将详细介绍我是如何做到这一点的。我希望这对任何有兴趣将强化学习应用于新领域的人有所帮助…...

java中的日期处理:只显示日期,不显示时间的两种处理方式
需要记录某个操作的操作时间,数据库中该字段为DATE类型; 插入数据的时候,使用数据库函数NOW()获取当前日期并插入: <insert id"batchInsertOrgTestersByProjectId">insert into project_org_testers(project_un…...
腾讯云AI代码助手编程挑战赛——贪吃蛇小游戏
作品介绍 贪吃蛇小游戏需要控制蛇的移动方向,使其吃掉地图上随机出现的食物,每吃掉一个食物,蛇的身体就会增长一格,是一款老少皆宜的小游戏,我们可以用腾讯ai助手生成全部代码,简单方便快捷。 技术架构 …...
水水水水水
为了拿推广卷,但不想把我原本完整的文章拆成零散的多篇,只能出此下策随便发一篇,认真写的都笔记专栏里 5G与未来网络 5G技术一直是近几年讨论的热点。它不仅仅是提升手机上网速度,更是对万物互联(IoT)的一次…...
Spring整合SpringMVC
目录 【pom.xml】文件; 新建【applicationContext.xml】文件 新建【springmvc.xml】文件; 配置【src/main/webapp/WEB-INF/web.xml】文件; 新建【com.gupaoedu.service.IUserService】; 新建【com.gupaoedu.service.impl.Use…...

【Rust自学】10.4. trait Pt.2:trait作为参数和返回类型、trait bound
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 说句题外话,写这篇的时间比写所有权还还花的久,trait是真的比较难理解的概念。 10.4.1. 把trait作为参数 继续以…...

嵌入式系统 (2.嵌入式硬件系统基础)
2.嵌入式硬件系统基础 2.1嵌入式硬件系统的组成 嵌入式硬件系统以嵌入式微处理器为核心,主要由嵌入式微处理器、总线、存储器、输入/输出接口和设备组成。 嵌入式微处理器 嵌入式微处理器采用冯诺依曼结构或哈佛结构:前者指令和数据共享同一存储空间…...
Linux 下 Vim 环境安装踩坑问题汇总及解决方法(重置版)
导航 安装教程导航 Mamba 及 Vim 安装问题参看本人博客:Mamba 环境安装踩坑问题汇总及解决方法(初版)Linux 下Mamba 及 Vim 安装问题参看本人博客:Mamba 环境安装踩坑问题汇总及解决方法(重置版)Windows …...

OpenAI 故障复盘 - 阿里云容器服务与可观测产品如何保障大规模 K8s 集群稳定性
本文作者: 容器服务团队:刘佳旭、冯诗淳 可观测团队:竺夏栋、麻嘉豪、隋吉智 一、前言 Kubernetes(K8s)架构已经是当今 IT 架构的主流与事实标准(CNCF Survey[1])。随着承接的业务规模越来越大,用户也在使…...

安卓触摸对焦
1. 相机坐标说明 触摸对焦需要通过setFocusAreas()设置对焦区域,而该方法的参数的坐标,与屏幕坐标并不相同,需要做一个转换。 对Camera(旧版相机API)来说,相机的坐标区域是一个2000*2000,原点…...

jupyter出现“.ipynb appears to have died. It will restart automatically.”解决方法
原因 解决方法:更新jupyter的版本 1.打开anaconda prompt 2、更新jupyter版本 在anaconda prompt输入以下指令 conda update jupyter如图:...
20250108-实验+神经网络
实验3. 神经网络与反向传播算法 3.1 计算图:复合函数的计算图 实验要求1:基于numpy实现 ( y 1 , y 2 ) f ( x 1 , x 2 , x 3 ) (y_1,y_2) f(x_1,x_2,x_3) (y1,y2)f(x1,x2,x3) 的反向传播算法(不允许使用自动微分)&a…...
【权限管理】CAS(Central Authentication Service)
CAS(Central Authentication Service)是一种广泛应用的 单点登录(SSO) 协议,它允许用户在一个集中式的身份验证系统中登录一次后,便可以无缝访问多个应用系统,而无需重复登录。CAS 通过统一的身…...

Golang笔记:使用net包进行TCP监听回环测试
文章目录 前言TCP监听回环代码演示 附:UDP监听回环 前言 TCP是比较基础常用的网络通讯方式,这篇文章将使用Go语言实现TCP监听回环测试。 本文中使用 Packet Sender 工具进行测试,其官网地址如下: https://packetsender.com/ TC…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...