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

MakeFile教程

前言

当我们需要编译一个比较大的项目时,编译命令会变得越来越复杂,需要编译的文件越来越多。其
次就是项目中并不是每一次编译都需要把所有文件都重新编译,比如没有被修改过的文件则不需要重
新编译。工程管理器就帮助我们来优化这两个问题。
MakeFile就类似于make工程管理的工作的脚本。用来告诉工程管理器如何正确的编译我们的程

在这里插入图片描述
依赖于目标的关系:
在MakeFile中依赖于目标是相互的,并不是绝对
在这里插入图片描述
比如 a.c 是生成a.o的一个依赖文件, 对于a.o 则是a.c的目标,a.o 又是image的依赖。
在我们使用make 进行编译的时候,工程管理器则会根据依赖于目标的关系来检查它们之间时间戳
关系,如果依赖有给你更新那么目标文件则需要执行。


安装make

sudo apt install make

语法

target : tgt_dependency1 tgt_dependency2 ...command

注意:
目标必须存在
依赖可以没有
命令前面必须是一个制表符TAB
Makefile 文件的命名一般是 Makefile没有后缀也没有前缀
如果规则中没有写依赖,则无论如何该规则该规则都会执行
如果目标已经存在,然后也没有写依赖则不执行该规则

在这里插入图片描述
示例1

Even:Jacy@echo "Hello Makefile"Jacy:ChuiHua@echo "Hello Even"ChuiHua:@echo "Hello Jacy"

执行

make // 工程管理器把第一个目标当成最终目标 Even
make Jacy // 告诉工程管理器 Jacy是我们需要的最终目标

示例2
在这里插入图片描述

./bin/main:./src/*.cgcc ./src/*.c -o ./bin/main -I./inc -L./lib -lmy_lib

示例3

animal_assembly : moose goose catcommand
moose : antlers hooves furcommand
goose : beak wings webbed_feet interest_in_breadcommand
cat : whiskers evil_personalitycommand

当不带参数调用时,将尝试构建目标animal_assembly
假设依赖项moosegoosecat已经在目录中可用,它将完全忽略它们的规则,并animal_assembly从现有内容构建
如果moosecat可用,但goose不可用,它会注意到moose存在,看到goose不存在,寻找要构建的规则goose,找到规则,构建goose,然后注意cat存在和构建animal_assembly
如果 moose, goose, cat都不存在,则必须使用可用规则构建所有这些。
一个好的经验法则是将最后和最重要的命令(对于我们的目的,最终将目标文件链接在一起成为可执行文件的命令)放在顶部。

变量:

  1. 变量和函数的展开(除规则的命令行以外),是在make读取Makefile文件时进行的,这里的变量包括了使用“=”定义和使用指示符“define”定义的变量。
  2. 变量可以用来代表一个文件名列表、编译选项列表、程序运行的选项参数列表、搜
    索源文件的目录列表、编译输出的目录列表和所有我们能够想到的事物。
  3. 变量名不能包括“:”、“#”、“=”、前置空白和尾空白的任何字符串。需要注意的是,
    尽管在GNU make中没有对变量的命名有其它的限制,但定义一个包含除字母、数字和下
    划线以外的变量的做法也是不可取的,因为除字母、数字和下划线以外的其它字符可能会在
    以后的make版本中被赋予特殊含义,并且这样命名的变量对于一些Shell来说不能作为环
    境变量使用。
  4. 变量名是大小写敏感的。变量“foo”、“Foo”和“FOO”指的是三个不同的变量。Makefile传统做法是变量名是全采用大写的方式。推荐的做法是在对于内部定义的一般变量(例如:目标文件列表objects)使用小写方式,而对于一些参数列表(例如:编译选项CFLAGS)采用大写方式,这并不是要求的。但需要强调一点:对于一个工程,所Makefile
    中的变量命名应保持一种风格,否则会显得你是一个蹩脚的开发者(就像代码的变量命名风格一样),随时有被鄙视的危险。
  5. 另外有一些变量名只包含了一个或者很少的几个特殊的字符(符号)。称它们为自
    动化变量。像“<”、“@”、“?”、“*”、“@D”、“%F”、“^D”等等,后面会详
    述之。
  6. 变量的引用跟Shell脚本类似,使用美元符号和圆括号,比如有个变量叫A,那么对
    他的引用则是$(A),有个自动化变量叫@,则对他的引用是$(@),有个系统变量是CC
    对其引用的格式是$(CC)。对于前面两个变量而言,他们都是单字符变量,因此对他们引用
    的括号可以省略,写成$A$@。`

自定义变量

顾名思义就是用户自己定义的变量

 A = apple # 定义并赋值变量
B = I love China
C = $(A) tree # $() 则是对某一个变量进行引用Even:
@echo $(A)
@echo $(B)
@echo $(C)

通过自定义变量来修改的Makefile 第二版本

TAG=./bin/main
SRC=./src/*.c
CC=gcc
O=-o
CONFIG=-I./inc -L./lib -lmy_lib$(TAG):$(SRC)$(CC) $(SRC) $(O) $(TAG) $(CONFIG)clean:rm ./bin/*

系统变量

在这里插入图片描述

自动化变量

自动化变量的值会自动发生变化
在这里插入图片描述

Makefile 中定义的变量有以下几种不同的方式:

1,递归定义方式:

A = I love $(B) # 在第一行使用到变量B但是还没有定义,以此管理器进行全文搜索找到B并引用
B = China

2,直接定义方式:

B = China
A := I love $(B)

此处,定义 A 时用的是所谓的“直接”定义方式,说白了就是如果其定义里出现有对
其他变量的引用的话,只会其前面的语句进行搜寻(不包含自己所在的那一行),而不是搜
寻整个文件,因此,如果此处将变量 A 和变量 B 的定义交换一个位置:

A := I love $(B) # A在B之前引用B 则为空
B = China

则 A 的值将不包含 China,因此在定义 A 时 B 的值为空。

3,条件定义方式:

有时我们需要先判断一个变量是否已经定义了,如果已经定义了则不作操作,如果没有
定义再来定义它的值,这时最方便的方法就是采用所谓的条件定义方式:

A = apple
A ?= I love China

此处对 A 进行了两次定义,其中第二次是条件定义,其含义是:如果 A 在此之前没有
定义,则定义为“I love China”,否则维持原有的值。

4,多行命令定义方式:

define commands
echo “thank you!echo “you are welcome.”
endef

此处定义了一个包含多行命令的变量commands,我们利用它的这个特点实现一个完
整命令包的定义。注意其语法格式:以define开头,以endef结束,所要定义的变量名必须
在指示符“define”的同一行之后,指示符define所在行的下一行开始一直到“end”所在行的
上一行之间的若干行,是变量的值。这种方式定义的所谓命令包,可以理解为编程语言中的
函数。

Makefile中的变量还有以下几种操作方式:

1,追加变量的值,例如:

A = apple
A += tree

这样,变量A的值就是apple tree。
2,修改变量的值,例如:

A = srt.c string.c tcl.c
B = $(A:%.c=%.o)

输出为srt.o string.o tcl.o
第三个版本:

TAG=./bin/main
SRC=./src/Input.c ./src/main.c ./src/Oper.c ./src/Output.c 
OBJ=$(SRC:%.c=%.o)
CC=gcc
O=-o
CONFIG=-I./inc $(TAG):$(OBJ)$(CC) $(^) $(O) $(@) $(CONFIG)%.o:%.c$(CC) $< -o $(@) $(CONFIG) -c clean:$(RM) ./bin/* ./src/*.o

函数

 $(subst FROM,TO,TEXT)

功能:将字符串 TEXT 中的字符 FROM 替换为 TO。
返回:替换之后的新字符串。
范例:

A = $(subst pp,PP,apple tree)

替换之后变量 A 的值是”aPPle tree”


$(wildcard PATTERN)

功能:获取匹配模式为 PATTERN 的文件名。
返回:匹配模式为 PATTERN 的文件名。
范例:

A = $(wildcard *.c)

假设当前路径下有两个.c 文件 a.c 和 b.c,则处理后 A 的值为:”a.c b.c”。


override一个变量,例如:

override CFLAGS += -Wall

.PHONY 来明确地告诉 Makefile,不要对 clean 运用任何隐式规则,不能运用隐式规则的目标被称为
伪目标

 .PHONY:clean 
用来修饰 clean 清空的工作不会被误以为是一个目标来执行

第四版本(通用版本)

TAG=./bin/main
SRC= $(wildcard src/*.c)
OBJ=$(SRC:%.c=%.o)
CC=gcc
override CONFIG += -I./inc $(TAG):$(OBJ)$(CC) $(^) -o $(@) $(CONFIG)%.o:%.c$(CC) $< -o $(@) $(CONFIG) -c 
clean:$(RM) ./bin/* ./src/*.o.PHONY:clean

在这里插入图片描述

相关文章:

MakeFile教程

前言 当我们需要编译一个比较大的项目时&#xff0c;编译命令会变得越来越复杂&#xff0c;需要编译的文件越来越多。其 次就是项目中并不是每一次编译都需要把所有文件都重新编译&#xff0c;比如没有被修改过的文件则不需要重 新编译。工程管理器就帮助我们来优化这两个问题…...

Spring使用mongoDB步骤

1. 在Linux系统使用docker安装mongoDB 1.1. 安装 在docker运行的情况下&#xff0c;执行下述命令。 docker run \ -itd \ --name mongoDB \ -v mongoDB_db:/data/db \ -p 27017:27017 \ mongo:4.4 \ --auth执行docker ps后&#xff0c;出现下列行&#xff0c;即表示mongoDB安…...

【蓝牙mesh】access层(接入层)协议介绍

【蓝牙mesh】access层&#xff08;接入层&#xff09;协议介绍 Access层简介 Access层定义了应用层如何使用upper协议层的接口&#xff0c;它不仅定义了应用层的格式&#xff0c;还定义了应用数据在upper层的加密和解密。当收到下层的数据包时&#xff0c;它会检查数据的netke…...

【一天一门编程语言】JavaScript 语言程序设计极简教程

JavaScript 语言程序设计极简教程 用 markdown 格式输出答案。 不少于3000字。细分到2级目录。 一、JavaScript 简介 1.1 什么是 JavaScript JavaScript 是一种由Netscape的LiveScript发展而来的脚本语言&#xff0c;是一种动态类型、弱类型、基于原型的语言&#xff0c;内…...

CMake调试器出炉:调试你的CMake脚本

Visual Studio 开发团队一直和 Kitware 紧密合作&#xff0c;致力于开发一个用于调试 CMake 脚本的调试器。 我们将继续这个工作&#xff0c;以便开发人员社区可以通过添加新功能和对其他 DAP 功能的支持来共同改进它。 我们很高兴地宣布&#xff0c;CMake 调试器的预览版现在…...

题解 # 二维矩阵最大矩形问题#

题目&#xff1a; 小明有一张N*M的方格纸&#xff0c;且部分小方格中涂了颜色&#xff0c;部分小方格还是空白。 给出N (2<Ns30)和M(2sMs30)的值&#xff0c;及每个小方格的状态(&#xff08;被涂了颜色小方格用数字1表示&#xff0c;空白小方格用数字0表示)&#xff1b; 请…...

奔四的路上,依旧倔强的相信未来

本文首发于2022年12月31日 原标题: 奔四的路上,依旧倔强的相信未来!–我的2022年终总结 读大学那几年,一直保持着写日记和做计划的习惯,还记得大学毕业刚开始打工的时候,我的床头的墙上一定会画一张表,写上一个月的计划和一周的计划 计划也会有完不成的时候,但加深了…...

61 k8s + rancher + karmada容器化部署

文章目录 一、什么是rancher二、为什么使用rancher三、rancher安装1、细部介绍四、图形化操作1、执行2、补充五、 karmada1、官网2、细部介绍一、什么是rancher 1、Rancher 是一个 全栈式 的 Kubernetes 容器管理平台,为你提供在任何地方都能成功运行 Kubernetes 的工具。 二…...

Vue3的新特性变化,上手指南!

文章目录一、Vue3相比Vue2&#xff0c;更新了什么变化&#xff1f;二、Proxy 代理响应式原理三、组合式 API (Composition API)setup()函数:ref()函数reactive()函数组合式 setup 中使用 Props 父向子传递参数计算属性watch&#xff08;数据监视&#xff09;watchEffect&#x…...

OllyDbg

本文通过吾爱破解论坛上提供的OllyDbg版本为例&#xff0c;讲解该软件的使用方法 F2对鼠标所处的位置打下断点&#xff0c;一般表现为鼠标所属地址位置背景变红F3加载一个可执行程序&#xff0c;进行调试分析&#xff0c;表现为弹出打开文件框F4执行程序到光标处F5缩小还原当前…...

记一次键盘维修,最终修复

我的笔记本是华硕的K45VD&#xff0c;是我亲人在高二那年买的&#xff0c;之后就一直给我用&#xff0c;距今2023年已经差不多13年&#xff0c;它承载了太多记忆。在大学期间也给它升级&#xff0c;重要的零部件基本没问题。只在大学时加了8G内存和一个240G固态&#xff0c;换了…...

LeetCode 155.最小栈

设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。实现 MinStack 类:MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void pop() 删除堆栈顶部的元素。int top() 获取堆栈顶部的元素。int getMin(…...

C++学习笔记-重载运算符和重载函数

重载的运算符是带有特殊名称的函数&#xff0c;函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样&#xff0c;重载运算符有一个返回类型和一个参数列表。 C 允许在同一作用域中的某个函数和运算符指定多个定义&#xff0c;分别称为函数重载和运算符重…...

Java —— JDBC

引入mysql链接 创建表格 Navicat查看建表代码双击要打开的表&#xff0c;右侧顶端点击ddl小方框 CREATE TABLE s (id int(6) NOT NULL,name varchar(20) COLLATE utf8_bin DEFAULT NULL,age int(11) DEFAULT NULL,gender varchar(2) COLLATE utf8_bin DEFAULT NULL,dept var…...

备战金三银四,熬夜半个月汇集大厂 Java 岗 1600 页面试真题

如果你不停地加班。却很少冒险&#xff0c;也很少学习&#xff0c;那你极大可能会陷入到内卷中。 为什么这么说呢&#xff1f;我们先来捋清楚「内卷」的概念&#xff1a; 「内卷化」简而言之就是&#xff1a;日复一日&#xff0c;越混越掉坑里。 所谓内卷化&#xff0c;指一种…...

9、面向对象、泛型与反射

目录一、构造函数二、继承与重写三、泛型四、反射1 - 反射的基本概念2 - 反射的基础数据类型3 - 反射APIa - 获取Type类型b - 获取struct成员变量的信息c - 获取struct成员方法的信息d - 获取函数的信息e - 判断类型是否实现了某接口五、reflect.Valuea - 空value判断b - 获取V…...

Python使用百度通用API进行翻译

想汉化StarUML这个软件&#xff0c;感觉工作量太大&#xff0c;想要用Python自动翻译。 结果网上找的一个个用不了&#xff0c;或者用一会儿就断。 于是自己手写了一个简单的&#xff0c;只有两个类&#xff1a;APIConfig和Translater 使用 demo my_api_config APIConfig(…...

JavaScript 弹窗

文章目录JavaScript 弹窗警告框确认框提示框换行JavaScript 弹窗 可以在 JavaScript 中创建三种消息框&#xff1a;警告框、确认框、提示框。 警告框 警告框经常用于确保用户可以得到某些信息。 当警告框出现后&#xff0c;用户需要点击确定按钮才能继续进行操作。 语法 wi…...

408复试day1

文章目录数据结构计算机组成原理操作系统计算机网络数据结构 深度优先遍历DFS&#xff1a; 首先访问图中起始顶点v&#xff0c;然后由v出发&#xff0c;访问与v邻接且未被访问的顶点v1&#xff0c;再访问与v1相邻的且未被访问的顶点v2……重复上述过程。当不能再继续向下访问时…...

gdb openocd jlink arm-a9调试

连接关系是这样的&#xff1a;gdb —> openocd —>&#xff08;这里需要两个xx.cfg配置文件&#xff09; jlink —> arm-a9板子 具体流程是这样的&#xff1a; 给jlink&#xff08;硬件调试器&#xff09;安装驱动&#xff0c;用USB Driver Tool这个软件&#xff0c;…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...

[USACO23FEB] Bakery S

题目描述 Bessie 开了一家面包店! 在她的面包店里&#xff0c;Bessie 有一个烤箱&#xff0c;可以在 t C t_C tC​ 的时间内生产一块饼干或在 t M t_M tM​ 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC​,tM​≤109)。由于空间…...

深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙

WebGL&#xff1a;在浏览器中解锁3D世界的魔法钥匙 引言&#xff1a;网页的边界正在消失 在数字化浪潮的推动下&#xff0c;网页早已不再是静态信息的展示窗口。如今&#xff0c;我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室&#xff0c;甚至沉浸式的V…...

【java面试】微服务篇

【java面试】微服务篇 一、总体框架二、Springcloud&#xff08;一&#xff09;Springcloud五大组件&#xff08;二&#xff09;服务注册和发现1、Eureka2、Nacos &#xff08;三&#xff09;负载均衡1、Ribbon负载均衡流程2、Ribbon负载均衡策略3、自定义负载均衡策略4、总结 …...

GB/T 43887-2024 核级柔性石墨板材检测

核级柔性石墨板材是指以可膨胀石墨为原料、未经改性和增强、用于核工业的核级柔性石墨板材。 GB/T 43887-2024核级柔性石墨板材检测检测指标&#xff1a; 测试项目 测试标准 外观 GB/T 43887 尺寸偏差 GB/T 43887 化学成分 GB/T 43887 密度偏差 GB/T 43887 拉伸强度…...