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

【Linux】Makefile秘籍

 > 🍃 本系列为Linux的内容,如果感兴趣,欢迎订阅🚩

> 🎊个人主页:【小编的个人主页

>小编将在这里分享学习Linux的心路历程✨和知识分享🔍

>如果本篇文章有问题,还请多多包涵!🙏
>  🎀   🎉欢迎大家点赞👍收藏⭐文章

> ✌️ 🤞 🤟 🤘 🤙 👈 👉 👆 🖕 👇 ☝️ 👍


目录

  

🐼前言 

   🐼预处理、编译、汇编和链接都在干什么??

   🐼为什么推荐使用Makefile???

   🐼make原理

 🐼make最佳实践


  

🐼前言 

一个可执行程序的生成通常需要经过预处理、编译、汇编和链接四个主要阶段。在 Linux 中,对于简单的单文件项目,我们常常可以直接使用 gcc code.c -o code 一步到位地生成可执行程序,然而,如果我们反复执行这条命令,依旧会编译,这就极大的浪费了时间和空间。对于大型项目,情况就复杂得多。大型项目通常包含多个 .c 文件、头文件以及其他资源文件。在这种情况下,手动管理这些文件的编译和链接过程不仅繁琐,而且容易出错。

为了简化大型项目的构建过程,Linux 引入了 make 工具。make 是一个强大的自动化构建工具,它可以根据项目中的文件依赖关系,自动执行预处理、编译、汇编和链接等步骤,生成最终的可执行程序。但要使用 make,我们需要在项目目录下编写一个 Makefile 文件,它定义了项目的构建规则。

因此,本篇博客将分享一个比较完善的 Makefile 编写模板,帮助大家更好地理解和使用 Makefile 来构建大型项目。

   🐼预处理、编译、汇编和链接都在干什么??

预处理:进行宏替换,去注释,条件编译替换,头文件展开

如果我们当前目录已有code.c这个文件,code.c内容是:

#include<stdio.h>#define N 100int main()
{printf("hello Linux,%d\n",N);#ifdef DEBUG_MODE
printf("Debug mode is enabled.\n");
#elseprintf("Debug mode is disabled.\n");
#endif#ifndef DEBUG_MODEprintf("This code is only compiled if DEBUG_MODE is not defined.\n");
#endif// 条件编译:根据变量值选择性编译
#if x > 5printf("x is greater than 5.\n");
#elif x == 5printf("x is equal to 5.\n");
#elseprintf("x is less than 5.\n");
#endifreturn 0;
}

我们执行gcc -E code.c -o code.i形成预处理后的.i文件(其中-o后是目标文件)

在我们目录下生成了,code.i文件,code.i其内容是

头文件展开:

预处理后确实发生进行宏替换,去注释,条件编译替换,头文件展开

头文件展开是将头文件的内容,拷贝到我们code.c中

条件编译和注释,本质是对代码的裁剪。

因此,在预处理之后,我们可以不需要在使用头文件了。

编译:形成汇编语言

我们使用gcc -S code.i -o code.s形成编译后的汇编文件code.s,这条指令的意思是从预处理文件开始,到编译完成就结束

code.s其内容是:

我们发现,确实是汇编语言。

我们再观察当前目录所有文件:

下面,我们使用gcc -c code.s -o code.o形成可重定位目标二进制文件。(也就是计算器认识的语言,二进制代码)。code.o

我们发现是一堆乱码。

我们尝试运行一下。

现在有个问题,为什么我们明明都已经形成了机器读懂的二进制文件,为什么还是运行不了。原因是我们所写的二进制文件,只是我们写的,并没有链接一些库,导致编译器不认识一些库函数(printf)等,只有和库库文件链接,才形成真的可执行程序。

因此,最后一步,我们进行和库链接。执行

使用命令:gcc code.o -o code.exe

程序被执行出来了!!!!!

   🐼为什么推荐使用Makefile???

 那我们既然能在命令行手动执行命令输出我们想到的程序,那我们为什么还要专门自已写一个Makefile,再使用make命令运行我们的可制成程序???

对于文件个数不多,我们还能处理,并且我们只要给计算机下达帮我们编译的命令,就能帮我们编译。那如果文件个数很多,比如有1000个.c文件,10个头文件等等,我们在通过命令行的方式手动编译,显得不现实,并且,我们已经有了可执行程序,我们再使用gcc code.o -o code.exe,编译器依旧会执行。

这点很致命,浪费了时间,效率。并且,我们也不好清理。因此,我们推荐使用Makefile根据项目中的文件依赖关系,自动执行预处理、编译、汇编和链接等步骤,生成最终的可执行程序并且完成清理工作。

   🐼make原理

make是Linux中一个内置命令

makefile是我们需要自已手动新建的文件

如果当前目录已经有了makefile文件,我们可以直接使用make命令

下面我们编写一个简单的makefile(我们直接通过.c生成可执行程序)

code.exe:code.cgcc code.c -o code.exe.PHONY:clean
clean:rm -rf code.exe 

其中code.exe,我们叫做目标文件,code.c是code.exe的依赖关系。打个比方,想要踢足球,就必须要有足球。

gcc code.c -o code.exe我们叫做依赖方法。其前面必须又空一个Tab键

关键字.PHONY后面修饰的目标是一个伪目标,而伪目标总是被执行。

那有个问题,什么叫做总是被执行????

而为什么第一个就不修饰成伪目标???

总是被执行,指的是,只要我们通过命令(make clean)执行,他都会被执行。而不是伪目标的,只会默认形成一个目标,就是从上向下的第一个目标,并且只会被执行一次,这里是make形成可执行程序,只会形成一次。

可是它是怎么知道make形成的可执行程序只执行一次,而.PHONY修饰的文件,总是被执行???

我们知道,Linux一切皆文件,文件=文件内容+文件属性。

系统知道该文件最近修改时间,因此可以对比.src和.exe文件修改时间。来决定是否需要重新编译。只要.exe文件比.src更新,就不修改。反之

而.PHONY无视修改时间,总是执行。

因此我们可以理解,下面这个现象:

我们再make,发现不让我make了。这就解释了,make只会从Makefile从上到下扫描第一个目标文件,并且只会执行一次。系统通过比对.src的修改时间,如果该文件没被修改之前,make无法执行,也就只会编译一次。而我们不希望,文件忘记清理。

最佳实践,可执行程序不要被修饰成.PHONY,而clean,我们希望修饰成.PHONY,总是被执行

这样让我们的编译效率尽可能高一点。

 🐼make最佳实践

下面我们编写几个Makefile,最后,引入我们通用的Makefile版本

既然是从Makefile从上往下依次找依赖关系code.exe依赖code.o依赖code.s依赖code.i依赖code.c。并且形成可执行程序要四步那Makefile先这么写;

code.exe:code.ogcc code.o -o code.exe
code.o:code.sgcc -c code.s -o code.o
code.s:code.igcc -S code.i -o code.s
code.i:code.cgcc -E code.c -o code.i.PHONY:clean
clean:rm -rf code.exe code.i code.o code.s 

使用命令make

形成一系列文件

调用make clean完成清理

其实:我们的习惯都是,先直接让单个程序形成单个的obj文件然后停下,然后再将所有obj文件链接。因此我们可以这么写;

code.exe:code.ogcc code.o -o code.exe
code.o:code.cgcc -c code.c
.PHONY:clean
clean:rm -rf code.exe code.o

但是这样写还是不够普遍性,对于文件名不同,改起来麻烦。所以,在Makefile,引入了$().

其中()中是变量名,可以是文件。因此,为了方便替换,我们可以这么写:

BIN=code.exe
SRC=code.c
OBJ=code.o
CC=gcc
LFLAGS=-o
CFLAGS=-c
RM = rm -rf$(BIN):$(OBJ)$(CC) $(LFLAGS) $(BIN) $(OBJ)
$(OBJ):$(SRC)$(CC) $(CFLAGS) $(SRC) $(LFLAGS) $(OBJ).PHONY:clean
clean:$(RM) $(BIN) $(OBJ)	

这样我们通过替换,可以直接修改文件名,以及依赖方法等。

并且,为了方便,我们可以直接将依赖方法中的$(BIN)换成$@ ,$(OBJ)换成$^

即将目标文件,换成@;依赖关系换成^

BIN=code.exe
SRC=code.c
OBJ=code.o
CC=gcc
LFLAGS=-o
CFLAGS=-c
RM = rm -rf$(BIN):$(OBJ)$(CC) $(LFLAGS) $@ $^
$(OBJ):$(SRC)$(CC) $(CFLAGS) $(SRC) .PHONY:clean
clean:$(RM) $(BIN) $(OBJ)	

但是我们这里只针对一个文件,当有多个文件时,我们希望可以处理所有的.c->.o文件 && .o->.exe文件,可以这么写:

对于所有的源文件

SRC=$(wildcard *.c)使用函数 wildcard 来查找当前目录下所有的 .c 文件,并将这些文件的列表赋值给变量 SRC

OBJ=$(SRC: .c=.o)将 SRC 变量中的每个 .c 文件扩展名替换为 .o,生成对象文件列表,赋值给变量 OBJ

%.o:%.c:定义了一个通用规则,目标是任意 .o 文件,依赖是对应的 .c 文件。规则的命令是 $(CC) $(CFLAGS) $<,这意味着使用 gcc 编译每个 .c 文件生成对应的 .o 文件

BIN=code.exe
SRC=$(wildcard: *.c)
OBJ=$(SRC:.c=.o)
CC=gcc
LFLAGS=-o
CFLAGS=-c
RM =rm -rf$(BIN):$(OBJ)$(CC) $(LFLAGS) $@ $^
%.o:%.c$(CC) $(CFLAGS) $<.PHONY:clean
clean:@$(RM) $(BIN) $(OBJ)	.PHONY:print
print:@echo $(SRC)@echo "--------------------------" @echo $(OBJ)

最后,为了完善Makefile,我们加入一些提示词,并使用@来过滤掉命令提示!

最佳实践

BIN=code.exe
SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o)
CC=gcc
LFLAGS=-o
CFLAGS=-c
RM =rm -rf$(BIN):$(OBJ)@$(CC) $(LFLAGS) $@ $^@echo "编译$^成为$@"
%.o:%.c@$(CC) $(CFLAGS) $<@echo "链接$<成为$@".PHONY:clean
clean:@$(RM) $(BIN) $(OBJ)@echo "清理完成".PHONY:print
print:@echo $(SRC)@echo "--------------------------" @echo $(OBJ)

为了测试:我们使用touch file{1..100}.c当前目录下创建100个空文件。

调用make命令:

最终编译101个.o文件形成code.exe可执行文件。

最后我们使用./code.exe,执行:

我们通过make指令执行自动化编译过程,Makefile允许定义一组规则来指定如何编译和链接程序。这样,我们一个比较完整的Makefile完成了。

   感谢你耐心地阅读到这里,你的支持是我不断前行的最大动力。如果你觉得这篇文章对你有所启发,哪怕只是一点点,那就请不吝点赞👍,收藏⭐️,关注🚩吧!你的每一个点赞都是对我最大的鼓励,每一次收藏都是对我努力的认可,每一次关注都是对我持续创作的鞭策。希望我的文字能为你带来更多的价值,也希望我们能在这个充满知识与灵感的旅程中,共同成长,一起进步。如果本篇文章有错误,还请大佬多多指正,再次感谢你的陪伴,期待与你在未来的文章中再次相遇!⛅️🌈 ☀️    

相关文章:

【Linux】Makefile秘籍

> &#x1f343; 本系列为Linux的内容&#xff0c;如果感兴趣&#xff0c;欢迎订阅&#x1f6a9; > &#x1f38a;个人主页:【小编的个人主页】 >小编将在这里分享学习Linux的心路历程✨和知识分享&#x1f50d; >如果本篇文章有问题&#xff0c;还请多多包涵&a…...

Python散点图(Scatter Plot):数据探索的“第一张图表”

在数据可视化领域,散点图是一种强大而灵活的工具,它能够帮助我们直观地理解和探索数据集中变量之间的关系。本文将深入探讨散点图的核心原理、应用场景以及如何使用Python进行高效绘制。 后续几篇将介绍高级技巧、复杂应用场景。 Python散点图(Scatter Plot):高阶分析、散点…...

Spring AI Alibaba快速使用

AI 时代&#xff0c;Java 程序员也需要与时俱进&#xff0c;这两个框架必须掌握。 一个是 Spring AI一个是 Spring Alibaba AI。 Spring AI 是一个AI工程领域的应用程序框架&#xff0c;它的目标是将 Spring生态系统的设计原则应用于人工智能领域。 但是&#xff0c; Spring…...

Redis 跳表原理详解

一、引言 在 Redis 中&#xff0c;有序集合&#xff08;Sorted Set&#xff09;是一种非常重要的数据结构&#xff0c;它可以实现元素的有序存储和高效查找。而实现有序集合的底层数据结构之一就是跳表&#xff08;Skip List&#xff09;。跳表是一种随机化的数据结构&#xff…...

安全地自动重新启动 Windows 资源管理器Bat脚本

安全地自动重新启动 Windows 资源管理器脚本 可以直接运行的 Windows 批处理脚本&#xff0c;用于安全地自动重新启动 Windows 资源管理器。该脚本会在杀死资源管理器之前检查是否有其他进程正在使用资源管理器相关的文件。 Bat脚本 echo off title 资源管理器安全重启工具 co…...

【C++模板】

模板初阶 前言1.定义模板2.函数模板2.1定义2.2实例化函数模板2.3模板参数的匹配原则 3.类模板3.1类模板实例化 前言 模板是C中泛型编程的基础&#xff0c;一个模板就是一个创建类和函数的蓝图或公式。 1.定义模板 假定我们希望编写一个函数来比较两个值&#xff0c;并指出第…...

基于Debian搭建FTP服务器

操作系统 Debian-9.6.0-amd64&#xff0c;图形化安装 基础操作 1.软件安装管理 命令方式&#xff1a; 在线安装 sudo apt-get install vim/ifconfig 查看安装软件 dpkg -l 图形化桌面方式 &#xff1a; 通过“软件管理”工具管理 2.网络管理 /etc/network/interfaces 3.文本…...

如果我的项目是用ts写的,那么如何使用webpack的动态导入功能呢?

在 TypeScript 项目中使用 Webpack 的动态导入&#xff08;Dynamic Imports&#xff09;功能&#xff0c;需要结合 TypeScript 的语法和 Webpack 的配置。以下是具体实现方法和注意事项&#xff1a; 一、基础配置 1. 修改 tsconfig.json 确保 TypeScript 支持动态导入语法&am…...

构建高效的LinkedIn图像爬取工具

一. 项目背景与目标 LinkedIn上的用户头像数据可以用于多种场景&#xff0c;例如&#xff1a; 人才招聘&#xff1a;通过分析目标职位候选人的头像&#xff0c;了解其职业形象。市场调研&#xff1a;收集特定行业从业者的头像&#xff0c;用于分析职业群体的特征。学术研究&a…...

在windows下安装windows+Ubuntu16.04双系统(下)

这篇文章的内容主要来源于这篇文章&#xff0c;为正式安装windowsUbuntu16.04双系统部分。在正式安装前&#xff0c;若还没有进行前期准备工作&#xff08;1.分区2.制作启动u盘&#xff09;&#xff0c;见《在windows下安装windowsUbuntu16.04双系统(上)》 二、正式安装Ubuntu …...

浅分析 PE3R 感知高效的三维重建

"近期&#xff0c;二维到三维感知技术的进步显著提升了对二维图像中三维场景的理解能力。然而&#xff0c;现有方法面临诸多关键挑战&#xff0c;包括跨场景泛化能力有限、感知精度欠佳以及重建速度缓慢。为克服这些局限&#xff0c;我们提出了感知高效三维重建框架&#…...

调和Django与Sql server2019的关系

数据库升级成sqlserver2019后&#xff0c;用户发现一些APP不能用了&#xff0c;检查发现是Django连接sqlserver的APP全部不能用了&#xff0c;页面打开都是500错误&#xff0c;进入Pycharm调试发现&#xff1a; 1.遇到错误1&#xff1a;django.db.backends.XXX错误 File "…...

【canvas】一键自动布局:如何让流程图节点自动找到最佳位置

一键自动布局&#xff1a;如何让流程图节点自动找到最佳位置 引言 在流程图、拓扑图和系统架构图设计中&#xff0c;节点布局往往是最令人头疼的问题。如果手动调整每个节点位置&#xff0c;不仅耗时费力&#xff0c;还难以保证美观性和一致性。本文将深入解析如何实现自动布…...

Flutter 学习之旅 之 flutter 使用 SQLite(sqflite) 实现简单的数据本地化 保存/获取/移除/判断是否存在 的简单封装

Flutter 学习之旅 之 flutter 使用 SQLite&#xff08;sqflite&#xff09; 实现简单的数据本地化 保存/获取/移除/判断是否存在 的简单封装 目录 Flutter 学习之旅 之 flutter 使用 SQLite&#xff08;sqflite&#xff09; 实现简单的数据本地化 保存/获取/移除/判断是否存在…...

[unity 组件] Content Size Fitter 横向填充不满解决办法

可以看到&#xff0c;当只有3个或者4个元素的时候&#xff0c;布局组件并没有将横向宽度占满来布局。之所以有此困惑的原因是我以为他的布局策略是&#xff0c;从左到右&#xff0c;从上至下&#xff0c;尽量占满空间&#xff0c;不够了再换行&#xff0c;其实不然。 5到6个元…...

Dify 项目开源大模型应用开发平台

Dify 是一款开源的大语言模型&#xff08;LLM&#xff09;应用开发平台&#xff0c;旨在简化生成式 AI 应用的创建、部署和持续优化流程。以下从多个维度对该项目进行详细介绍&#xff1a; 一、项目定义与核心功能 Dify 的核心定位是结合 后端即服务&#xff08;BaaS&#xff…...

使用 `pytest` 框架时,可以通过极限封装将 YAML 文件的读取、解析

在使用 pytest 框架时,可以通过极限封装将 YAML 文件的读取、解析和测试用例的通用逻辑封装成共享的方法或 fixture,从而减少重复代码。以下是详细的实现步骤和示例。 1. 封装 YAML 文件读取和解析 将 YAML 文件的读取和解析逻辑封装到一个工具函数中,供所有测试用例调用。…...

算法刷题记录——LeetCode篇(2) [第101~200题](持续更新)

(优先整理热门100及面试150&#xff0c;不定期持续更新&#xff0c;欢迎关注) 101. 对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&am…...

ruoyi 小程序使用笔记

1.上传图片 页面 <uni-forms-item label"退休证明(退休证)" name"retire"><uni-file-picker ref"imageUploadRetire" :limit"1" :auto-upload"false" select"upload"/> </uni-forms-item>js …...

计算机网络——总结

01. 网络的发展及体系结构 网络演进历程 从1969年ARPANET的4个节点发展到如今覆盖全球的互联网&#xff0c;网络技术经历了电路交换到分组交换、有线连接到无线覆盖的革命性变革。5G时代的到来使得网络传输速度突破10Gbps&#xff0c;物联网设备数量突破百亿级别。 网络体系…...

Stable Diffusion lora训练(一)

一、不同维度的LoRA训练步数建议 2D风格训练 数据规模&#xff1a;建议20-50张高质量图片&#xff08;分辨率≥10241024&#xff09;&#xff0c;覆盖多角度、多表情的平面风格。步数范围&#xff1a;总步数控制在1000-2000步&#xff0c;公式为 总步数 Repeat Image Epoch …...

再学:ERC20-Permit2、SafeERC20方法 详解ERC721,如何铸造一个NFT以及IPFS的作用

目录 1.Permit2 2.尽量使用Safe方法 3.ERC721 4. 铸造NFT 1.Permit2 针对没有permit的代币实现的线下签名方式 通过approve方法&#xff0c;让Permit2拿到无限次数的授权。拿到授权之后&#xff0c;Permit2会生成签名。 当用户需要转账的时候&#xff0c;Permit2会发送签…...

Docker 存储

目录挂载 在执行run时设置参数-v即可实现目录映射, 实现原理会在宿主机器创建一个空文件夹 # 挂载宿主机的 /data 目录到容器的 /app 目录 docker run -d -v /data:/app --name my-app my-image # 挂载 docker 内的 /usr/share/nginx/html 目录到本地机的 /app/nghtml docker…...

详细介绍VUE,带你了解VUE!!!

Vue.js 是一个渐进式的 JavaScript 框架&#xff0c;用于构建用户界面。它的核心库专注于视图层&#xff0c;易于与其它库或现有项目进行集成&#xff0c;同时也可以与现代工具链和支持库结合使用&#xff0c;成为一个完整的开发框架。 以下是关于 Vue.js 的详细资料&#xff…...

C++语法之命名空间二

A.h头文件中代码&#xff1a; namespace a {void 输出(); }; A.cpp源文件中代码&#xff1a; #include <iostream> #include "A.h" void a::输出() {std::cout << "A.h里的输出函数" << std::endl; } B.h头文件中代码&#xff1a; …...

【STM32】I²CC通信外设硬件I²CC读写MPU6050(学习笔记)

相关文章笔记&#xff1a; 【STM32】I2C通信协议&MPU6050芯片-学习笔记-CSDN博客 【江协科技STM32】软件I2C协议层读写MPU6050驱动层-CSDN博客 IC通信外设 IC外设简介 STM32内部集成了硬件I2C收发电路&#xff0c;可以由硬件自动执行时钟生成、起始终止条件生成、应答…...

Android Room 框架公共模块源码深度剖析(四)

一、引言 在 Android 开发中&#xff0c;数据持久化是一个常见的需求。Android Room 框架作为 Android Jetpack 组件的一部分&#xff0c;为开发者提供了一个抽象层&#xff0c;使得在 SQLite 数据库上进行数据操作变得更加简单和高效。Room 框架包含多个模块&#xff0c;其中…...

NumPy系列 - 创建矩阵

目录 前传直接创建数组就只是创建数组1. np.array()2. np.arange()3. np.ones()4. numpy.ones_like()5. np.zeros()6. numpy.zeros_like() 定义数据类型 参考资料 前传 由于&#xff0c;某人在上智能相关课程的时候&#xff0c;总想着一大堆的事情&#xff0c;统计股市涨跌&am…...

能“嘎嘎提升”提升用户居住体验的智能家居物联网框架推荐!

智能家居在日常生活中给我们的带来了更多的便利&#xff0c;更让有些用户切实地体会到了科技的魅力&#xff0c;对于想要打造属于自己的智能家居氛围感的用户们&#xff0c;以下是一些能够帮助提升居住体验的智能家居物联网框架及应用&#xff1a; 1. 涂鸦智能&#xff08;Tuy…...

python-leetcode 60.分割回文串

题目&#xff1a; 给定一个字符串S,请将S分割成一些子串&#xff0c;使每个子串都是回文串&#xff0c;返回S所有可能的分割方案 方法一&#xff1a;回溯深度优先搜索 1. 主要思想 使用 深度优先搜索&#xff08;DFS&#xff09; 遍历 s 的所有可能划分方式。使用 回溯&…...

Android Jetpack Compose介绍

Android Jetpack Compose Android Jetpack Compose 是 Google 推出的现代 UI 工具包&#xff0c;用于以声明式的方式构建 Android 应用的 UI。它摒弃了传统的 XML 布局方式&#xff0c;完全基于 Kotlin 编写&#xff0c;提供了更简洁、更强大的 UI 开发体验。以下是 Compose 的…...

文档搜索引擎项目测试

目录 设计测试用例 功能测试 文档搜索功能 具体的逻辑 文档显示搜索结果功能 自动化测试 功能类介绍 最终测试套件的测试结果 性能测试 查看聚合报告 每秒处理事务数/吞吐量(TPS) 响应时间 生成测试报告 界面测试 初始页面 搜索页面 总结 后续改进: 设计测试…...

Vue3项目技术点记录

vue3项目技术点笔记 1 环境变量 - 不同环境用不同的配置 环境变量命名:.env.produciton .env.development Vite.config.ts 配置 envDir:‘’ 链接: VUE3+Vite 环境变量配置 2 axios的封装 http请求拦截,响应拦截。 src下建立公共文件夹Utils下建立request.ts import axios…...

一和零 (leetcode 474

leetcode系列 文章目录 一、核心操作二、外层配合操作三、核心模式代码总结 本题是一个01背包问题&#xff0c;只是背包是一个二维数组的背包&#xff0c;分别为0的个数不能超过m&#xff0c;1的个数不能超过n&#xff0c;而物品就是题目中的字符串&#xff0c;其容量为0和1的…...

Linux vim mode | raw / cooked

注&#xff1a;机翻&#xff0c;未校。 vim terminal “raw” mode Vim 终端 “raw” 模式 1. 原始模式与已处理模式的区别 We know vim puts the terminal in “raw” mode where it receives keystrokes as they are typed, opposed to “cooked” mode where the command…...

利用Linux的I2C子系统和i2c-tools工具集写出的对I2C设备AP3216C读写的应用程序

前言 由于NXP官方提供的BSP里已经包含了其片上I2C控制器的驱动并接入到了Linux的I2C子系统&#xff0c;所以我们可以直接去写与I2C有关的应用程序了。 在本篇博文中我们用两种方式对I2C设备AP3216C进行读写操作。 第一种&#xff1a;直接利用Linux的I2C子系统对I2C设备AP3216…...

springCloud集成tdengine(原生和mapper方式) 其二 原生篇

mapper篇请看另一篇文章 一、引入pom文件 <!-- TDengine 连接器--><dependency><groupId>com.taosdata.jdbc</groupId><artifactId>taos-jdbcdriver</artifactId><version>3.5.3</version></dependency>二、在nacos中填…...

gralloc usage flags

下面这些示例主要说明了 gralloc usage flags 在图像处理和多媒体应用中如何影响性能和正确性。让我们逐个详细分析每个问题的 根因 和 修复方案&#xff0c;并深入解析 gralloc 标志对 缓存管理 和 数据流 的影响。 ✅ Example 1: 长曝光快照耗时异常 &#x1f4cc; 问题描述…...

RIP路由欺骗攻击与防御实验详解

一、基础网络配置 1. 路由器R1配置 interface GigabitEthernet0/0/0ip address 192.1.2.254 255.255.255.0 ! interface GigabitEthernet0/0/1ip address 192.1.3.254 255.255.255.0 ! router rip 1version 2network 192.1.2.0network 192.1.3.0 2. 路由器R2配置 interface…...

在 Linux下使用 Python 3.11 和 FastAPI 搭建带免费证书的 HTTPS 服务器

在当今数字化时代&#xff0c;保障网站数据传输的安全性至关重要。HTTPS 协议通过使用 SSL/TLS 加密技术&#xff0c;能够有效防止数据在传输过程中被窃取或篡改。本教程将详细介绍如何在 Ubuntu 22.04 系统上&#xff0c;使用 Python 3.11 和 FastAPI 框架搭建一个带有免费 SS…...

[QMT量化交易小白入门]-三十五、如何将聚宽策略信号转为QMT实盘交易

本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。 QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。 文章目录 相关阅读一、聚宽模拟运行:构建交易策略的基础在聚宽…...

国思RDIF低代码快速开发框架 v6.2版本发布

1、平台介绍 国思RDIF企业级低代码开发平台&#xff0c;给用户和开发者最佳的框架平台方案&#xff0c;为企业快速构建跨平台、企业级的应用提供强大支持。致力于解决企业信息化项目交付难、实施效率低、开发成本高的问题。能帮助企业快速构建美观易用、架构专业、安全可控的企…...

学习笔记 ASP.NET Core Web API 8.0部署到iis

一.修改配置文件 修改Program.cs配置文件将 if (app.Environment.IsDevelopment()) {app.UseSwagger();app.UseSwaggerUI(); }修改为 app.UseSwagger(); app.UseSwaggerUI(); 二.安装ASP.NET Core Runtime 8.0.14 文件位置https://dotnet.microsoft.com/en-us/download/do…...

【Linux】信号:产生信号

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;linux笔记仓 目录 01.信号信号处理简单理解信号的发送和保存由软件产生的信号由硬件&#xff08;异常&#xff09;产生的信号 01.信号 进程信号是操作系统提供的一种异步通知机制&#xff0c;用于…...

单片机自学总结

自从工作以来&#xff0c;一直努力耕耘单片机&#xff0c;至今&#xff0c;颇有收获。从51单片机&#xff0c;PIC单片机&#xff0c;直到STM32&#xff0c;以及RTOS和Linux&#xff0c;几乎天天在搞:51单片机&#xff0c;STM8S207单片机&#xff0c;PY32F003单片机&#xff0c;…...

Idea集成docker通过ca加密实现镜像打包

​ Idea集成docker实现镜像打包_ideadocker镜像打包-CSDN博客 ​ 之前通过这种方式虽然可以实现idea通过maven打jar包的同时把docker镜像也进行打包&#xff0c;但是这种方式存在很大漏洞&#xff0c;就是服务器的2375端口大开&#xff0c;任何人拿着idea通过这种方式都可以连…...

【Prometheus】prometheus标签替换label_replace,动态修改生成标签,增强查询的灵活性和表达能力

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…...

蓝桥杯 之 暴力回溯

文章目录 数字接龙小u的最大连续移动次数问题 在蓝桥杯中&#xff0c;十分喜欢考察对于网格的回溯的问题&#xff0c;对于这类的问题&#xff0c;常常会使用到这个DFS和BFS进行考察&#xff0c;不过无论怎么考察&#xff0c;都只是会在最基础的模本的基础上&#xff0c;根据这个…...

在K8S中挂载 Secret 到 Pod

在 Kubernetes 里&#xff0c;把 Secret 挂载到 Pod 中有两种主要方式&#xff1a;作为卷挂载和作为环境变量挂载。下面为你提供相应的代码示例。 作为卷挂载 Secret 将 Secret 作为卷挂载到 Pod 时&#xff0c;Secret 的每个键会成为挂载目录下的一个文件&#xff0c;文件内…...

LINUX网络编程API原型详细解析

1. 网络体系 1.1. 简介 网络采用分而治之的方法设计&#xff0c;将网络的功能划分为不同的模块&#xff0c;以分层的形式有机组合在一起。 每层实现不同的功能&#xff0c;其内部实现方法对外部其他层次来说是透明的。每层向上层提供服务&#xff0c;同时使用下层提供…...