makefile教程(1)

makefile教程

makefile是什么:

makefile是用户自行完成的IDE(integrated development environment集成开发环境)程序,与传统的操作系统下的编译不同,makefile可以通过用户自行安排,决定文件的编译顺序,决定哪些文件需要编译,哪些文件需要重复编译等各种复杂的操作

使用makefile的好处:

可自由编译的好处,能够指定文件编译,将繁杂的编译方法集成到一个makefile文件中,然后使用make进行一键编译,极大的提高了开发效率

关于程序的编译和链接:

关于gcc编译成可执行文件的命令,以及对应命令下生成的文件后缀

命令文件
gcc -E 预处理(宏展开)*.i
gcc -S 编译(生成汇编代码)*.s
gcc -c 汇编(生成机器码)*.o(unix下)
gcc -o 链接(把大量的.o文件合成生成可执行文件) (主要链接的是函数和全局变量)对于a.out文件的重命名可执行文件
  • 链接 link

把大量的.o文件合并生成可执行文件

主要链接的就是函数和全局变量,而存放函数和全局变量的地方通常称为库文件 .lib文件

在unix下也叫做.a文件

  • 编译

在编译时,编译器只会管你程序的语法是否正确,函数和变量是否已经声明,函数如果没有声明也没关系,只会报警告,而在链接这一步,链接器会在所有的.o文件中寻找这个函数,如果没有找到,就报链接错误码

makefile内核

所有的makefile的实际都是:编译+链接

只要记住编译+链接就行

  1. 如果这个工程没有被编译过,那么所有的.c文件都要编译并被链接
  2. 如果这个工程已经编译,但是修改了.c文件,我们需要编译修改的.c文件,并连接目标程序
  3. 如果这个工程已经编译,但是修改了.h文件,我们需要编译修改的.h文件,并连接目标程序

makefile的使用规则:

一共有五大原则:显示规则、隐式规则、变量定义、文件指示、注释说明

显示规则

目标…:依赖…

命令

  • 目标:可以是个文件(object文件或者是可执行文件),也可以是个标签label

  • 依赖:要生成target目标的所需要文件或者是目标

  • 命令:就是使用make之后所要执行的命令(shell命令)

当依赖中的文件比目标中的文件要新的话,就必须执行命令中的内容,这就是makefile的核心

请添加图片描述

请添加图片描述

其中“ \ ”表示换行符

clean不是一个文件,而是一个动作名,我们要使用clean,就需要make clean。而且clean后面也不需要出现依赖。

所以我们也可以在makefile中定义不用的编译或者与编译无关的命令,比如程序的打包,程序的备份等

怎么使得make时会判断哪些是不需要makefile的命令呢,例如clean这个动作写入makefile时当我们使用make时不会自动执行,其中的原理在哪

这就谈到make是如何工作的

make是如何工作的

  1. make会首先在当前文件夹中搜寻makefile或者是Makefile文件
  2. 读入被include的其他makefile
  3. 初始化定义的变量
  4. 为所有的目标建立依赖关系链
  5. 顺序执行第一个target,并且把target作为最终的目标文件,也就是一切都是为了第一个target
  6. make会比较依赖和目标的文件时间戳,如果依赖比目标的文件时间新,则会重新生成target文件
  7. 根据最终目标文件的依赖,首先会查找是否存在这些依赖,如果不存在则会按照是否makefile中存在依赖文件的生成方式,有的话就会执行下去,没有的话就直接退出报错
  8. 为什么要单独对clean进行make,是因为:

第一个target并没有直接或间接利用clean

clean之后没有存在依赖

如果我们改变了“command.h”,那么,kdb.o、command.o 和 files.o

都会被重编译,并且,edit 会被重新链接。

makefile中使用变量(变量定义)

  • 变量的定义
  1. 就好比C语言中宏的作用,当我们在添加或者修改依赖时,至少要修改三遍以上,所以干脆用个宏,修改一处就可以,一般宏设置为 “OBJ、OBJECT、OBJS ”
  • 变量的使用
  1. 一般是变量 = 依赖,首先先把变量声明好
  2. 调用变量时使用 $(OBJ)
  • 自动化变量

$< 和 $@称为自动化变量

$@表示目标文件

$<表示依赖文件

makefile自动推导(隐式规则)

一般来说make会自动推导出依赖文件,例如我们的main.o文件就是由main.c得到的,但我们没必要去写:

main.o:main.c defs.h

​ cc -c main.c

直接用 main.o:defs.h

也只是.o对于.c,其余依赖也要补充

请添加图片描述

引用其余的makefile(文件指示)

  • 使用include关键字

include + Makefilename(路径或者通配符)

路径如果没有设置,将会选择是当前文件夹下的makefile

“如果 make 执行时,有“-I”或“–include-dir”参数,那么 make 就会在这个参数所指定”

这个后面再说

  • 环境变量MAKRFILES

如果在当前环境中使用了环境变量MAKEFILES

那么make时会把这个变量MAKEFILES中的值做一个inlcude的动作

但是这个环境变量中的值如果是其他的makefile文件,则会用空格分开

这个变量中的target值在make时也不会起作用,依赖文件发生错误也不会管

通配符的使用

如果要使用一系列的类似的文件,一般使用通配符(* ,?,[…])来概括:

如果文件名中有通配符,我们可以使用 “\ *”来表示真正的“ * ”字符

object = *.o 表示的就是 *.o文件,而没有展开

object = $(wildcard *.o) 就可以得到一个展开后的变量合集

文件搜寻

  • 特殊变量 VPATH

VPATH表示目标或者依赖文件的寻找目录

比如:VPATH = src:…/header

表示目标或者依赖文件寻找的目录为src 或者上一层的header目录

其中:表示目录的分隔

  • 关键字 vpath

可以指定某个文件在哪个目录下寻找:vpath < pattern模式> < directories>

vpath %.h …/header

表示所有的.h文件都可以在上一层的header目录下找到

vpath %.h

表示符合模式%.h的文件目录

vpath

表示清除所有已被设置好了的文件搜索目录

当然目录的优先级最高的还是当前目录下的

连续使用vpath关键字来指定不同的搜索方式:

vpath %.c first

vpath % second

vpath %.c third

其表示“.c”结尾的文件,先在“first”目录,然后是“second”,最后是“third”目录

这里second比较特殊,什么文件都可以在second中搜索,比较浪费时间

可以通过改写成:

vpath %.c first:third

vpath % second

而上面的语句则表示“.c”结尾的文件,先在“first”目录,然后是“third”目录,最后才是“second”目录

伪目标

什么是伪目标

伪目标不是一个文件,所以无法使用依赖关系,我们必须使用一个特殊的标签来注明,使用时也得使用make+标签来表示

伪目标的使用要求

  • 不能与其他目标名重复,我们可以使用.PHONY来指明这是个伪目标

.PHONY:clean

  • 总是被执行的

伪目标同样可作为默认目标,就可以放在开头

all : prog1 prog2 prog3

.PHONY : all

由于伪目标总是被执行的,all作为一个伪目标,如果说prog1更新了,或者是prog3更新了,all也会更新

  • 伪目标也可以成为依赖

.PHONY : cleanall cleanobj cleaniff

cleanall : cleanobj cleaniff

多目标 涉及到函数后续

有时候多个目标可以共同使用一个依赖,这个叫做多目标

静态模式

更好的服务于多目标的使用

目标集合:目标集模式 依赖目标集模式

targets:%.o :%.c

表示对所有的.o文件进行了二次定义,也就是说去掉了.o的结尾,加上了.c的这个结尾

eg1:

objects = first.o second.o

$(object) : %.o : %.c

$(CC) -c $(CFLAGS) $< -o $@

也就是在objects这个变量中 将所有的.o文件修改成.c文件,所以修改之后我们的依赖目标集就是 first.c second.c

所以 < 表示依赖目标集, < 表示依赖目标集, <表示依赖目标集,@表示目标集

eg2:

file = 1.o 2.o 3.elc

( f i l t e r (filter %.o, (filter(file)) : %.o : %.c

gcc -c $< -o $@

$(filter %.elc,%(file)) : %.elc : %.el

emacs -f batch-byte-compile $<

filter是个函数,第一个参数是过滤条件,第二个参数过滤源

自动生成依赖性

对于每个.c文件,我们都得清楚包含了哪些头文件,这就大大增加了压力,但GNU编译器存在自动搜索头文件功能,使用 -MM参数

gcc -MM main.c = main.o : main.c defs.h

我们要为每个文件生成.d 文件之后才能自动化生成依赖关系

%.d : %.c

gcc -M $< > @ . @. @.$$$

书写命令

  • @

我们用“@”字符在命令行前,那么,这个命令将不被 make 显示出来

如果你要让上一条命令的结果应用在下一条命令时,你应该使用分号分隔这两条命令。比如你的第一条命令是 cd 命令,你希望第二条命令得在 cd 之后的基础上运行,那么你就不能把这两条命令写在两行上,而应该把这两条命令写在一行上,用分号分隔。

加一个减号“-”(在 Tab 键之后),标记为不管命令出不出错都认为是成功的

嵌套执行make

在不同的文件夹中编写不同的makefile,再由总控的makefile进行控制,可以有效的进行模块化的维护

例如我们在subdir下有个makefile,如果我们要在总控makefile中使用:

subsystem:

​ cd subdir && $(MAKE)

我们的make需要一点参数,所以定义成变量比较合适

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/269764.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

将elementUI,NaiveUI的progress环形进度条设置为渐变色

需求 &#xff1a;进度条要有一个渐变效果。效果图&#xff1a; NaiveUI和elementUI的官方progress组件都是只能设置一种颜色&#xff0c;不符合需求所以改一下。 其实NaiveUI和elementUI设置进度条的实现方式基本一样都是使用svg渲染出两个path&#xff0c;第一个是底色&…

ssh工具 向指定的ssh服务器配置公钥

此文分享一个python脚本,用于向指定的ssh服务器配置公钥,以达到免密登录ssh服务器的目的。 效果演示 🔥完整演示效果 👇第一步,显然,我们需要选择功能 👇第二步,确认 or 选择ssh服务器 👇第三步,输入ssh登录密码,以完成公钥配置 👇验证,我们通过ssh登录…

如何使用Docker将.Net6项目部署到Linux服务器(二)

目录 二 安装Redis 2.1 基本安装 2.1.1 下载Redis 2.1.2 解压并安装Redis 2.1.3 编译Redis 2.1.3 配置config文件 2.1.4 配置redis服务 2.1.5 关闭redis服务 2.2 Docker安装 2.2.1 拉取镜像 2.2.2 查看镜像 2.2.2 创建挂载目录 2.2.3 创建配置文件 2.2.4 创建容器…

微信商家费率0.2怎么申请

不管是微信还是支付宝&#xff0c;商户最低的收款手续费率可以达到0.2%费率。一般我们普通商户的收款费率一般在0.6左右&#xff0c;当然也有使用0.3的&#xff0c;也就是1万元的费率是30-60块钱&#xff0c;对于一些流水比较大的商家来说&#xff0c;确实很有必要把这个手续费…

ThunderSearch(闪电搜索器)_网络空间搜索引擎工具_信息收集

文章目录 ThunderSearch简介1 项目地址2 使用方式2.1 配置文件config.json说明2.2 构建和运行 3 使用式例 ThunderSearch简介 ThunderSearch&#xff08;闪电搜索器&#xff09;是一款使用多个(【支持Fofa、Shodan、Hunter、Zoomeye、360Quake网络空间搜索引擎】网络空间搜索引…

Vue爱好者必看!九款常用UI组件库,助力项目快速搭建!

Vue通常用于构建用户界面和单页应用程序。产品开发者可以从简单的组件开始创建&#xff0c;并逐渐衍生出更复杂的前端平台。通过合理应用UI组件库&#xff0c;设计师可以快速提高整体设计效率&#xff0c;更好地优化产品从外观结构到交互体验。本节将盘点9个常用的VueUI组件库。…

Linux与Bash 编程——Linux文件处理命令-L1

目录&#xff1a; linux系统与shell环境准备 Linux系统简介操作系统简史Linux的发行版&#xff1a;Linux与Windows比较&#xff1a;Linux安装安装包下载Linux的访问方式远程登录方式远程登录软件&#xff1a;mobaxterm的使用&#xff1a;使用电脑命令行连接&#xff1a;sshd的…

(1)(1.11) SiK Radio v2(一)

文章目录 前言 1 概述 2 特点 3 状态LED灯 前言 SiK 遥测无线电是在自动驾驶仪和地面站之间建立遥测连接的最简单方法之一。本文提供了如何连接和配置无线电的基本用户指南。 3DR Radio v2&#xff08;SiKRadio 的消费者版本&#xff09; &#xff01;Note 本页面以前的…

网站配置域名实例

目录 网站配置 网站备案 如果希望你的网站对外提供互联网信息服务还有非常关键的两个动作&#xff0c;那就是&#xff1a;为网站配置、为网站备案。 由于IP地址不方便记忆并且不能显示地址组织的名称和性质&#xff0c;人们设计出了域名&#xff0c;并通过域名系统&#xff…

redis主从扩容案例

redis3主3从&#xff0c;请参见&#xff1a;https://blog.csdn.net/weixin_49456013/article/details/134930716?spm1001.2014.3001.5501 现在需要进行扩容&#xff0c;变成4主4从&#xff0c;主要步骤如下&#xff1a; 1.新建6387、6388两个节点并启动 docker run -d --na…

“双十一、二” 业务高峰如何扛住?韵达快递选择 TDengine

小 T 导读&#xff1a; 为了有效处理每日亿级的数据量&#xff0c;早在 2021 年&#xff0c;韵达就选择用 TDengine 替代了 MySQL&#xff0c;并在三台服务器上成功部署和上线了 TDengine 2.0 集群。如今&#xff0c;随着 TDengine 3.0 版本的逐渐成熟&#xff0c;韵达决定将现…

如何实现https密钥对登录方式

先安装docker yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo systemctl start docker.service systemctl enable docker.service yum install -y docker…

三叠云食堂管理系统:打造智慧食堂,提升运营效率与服务质量

今天&#xff0c;人们越来越注重生活品质和食品安全。特别是在学校食堂这样的公共场所&#xff0c;如何确保食品的安全、营养和健康成为了重中之重。食堂&#xff0c;作为学校和各类企业的重要部分&#xff0c;也迫切需求升级改革。三叠云食堂管理系统&#xff0c;就是为满足食…

猫头虎分享2023年12月17日博客之星候选--领域赛道博主文章数据

猫头虎分享2023年12月17日博客之星候选–领域赛道博主文章数据 博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开…

华为数通方向HCIP-DataCom H12-831题库(多选题:241-249)

第241题 (NEW) 以下哪些操作可能会影响客户网络的正常运行? A、从设备上下载日志 B、软件升级 C、路由协议配置变更 D、debug核心交换机上转发的所有IP报文 答案:ABCD 解析: 第242题 对于防火墙的默认安全区 Trust 和 Untrust 的说法,正确的有 A、从 Trust 区域访问 Untr…

ES5语法数组遍历、字符串、对象新增方法

ES5数组遍历forEach\filter\some\every\map、字符串trim、对象keys\defineProperty新增方法   Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎&#xff0c;能够解决不断涌现出的各种用例。作为 Elastic Stack 的核心&#xff0c;它集中存储您的数据&#xff…

德勤中国合伙人姚承懿:只是“线上化”的数字化转型不会成功

投资者们都期待超出预期的增长&#xff0c;倾向规避未知风险。当下的宏观经济形势复杂&#xff0c;外部条件多变&#xff0c;那些善于驾驭风险&#xff0c;给市场以确定性的企业&#xff0c;能够得到投资者更多的青睐。 合规与增长是支撑上市公司市值的关键要素。有统计数据显…

GrayLog日志平台的基本使用-docker容器日志接入

1、/etc/docker/daemon.json中加入如下配置并重启服务 [rootlocalhost src]# cat /etc/docker/daemon.json { "registry-mirrors": ["https://dhq9bx4f.mirror.aliyuncs.com"], "log-driver": "gelf", "log-opts":…

vscode中使用GitHub Copilot Chat

文章目录 一、什么是Github Copilot Chat二、安装使用三、如何使用1. 聊天功能2. 内联功能 一、什么是Github Copilot Chat GitHub Copilot Chat 由 OpenAI 的 GPT-4 大型多模态模型提供支持&#xff0c;能带来更准确的代码建议、解释和指导。GitHub Copilot Chat 的内联功能可…

售前工程师宝典:整理服务器最全知识点

如何保证服务器可以支持百万用户访问&#xff1f;服务器品牌有哪些&#xff1f;如何选购服务器&#xff1f;对于这些问题&#xff0c;今天我们就一起来看下关于服务器的相关知识。 假如你开发了一个网站或者一个app把他放到服务器上&#xff0c;之后你把它发布到了网上&#x…