129 Linux 系统编程7 ,make 的编写和解析

前文中,我们有多少个.c文件,就需要build 出来多少个.o文件

假设我们的项目很大,怎么管理这些 .c文件呢?

这里就要学习一个make文件的编写了。

makefile 本质上是一个脚本语言

脚本语言实际上就是将一系列命令放在一起执行

makefile 的用途:

项目代码编译管理

节省编译项目时间

一次编译终身受益

Makefile 工作内容:

makefile 会把遇见的第一条指令作为他的终极指令

但是如果开发者在前面加了关键字 ALL

就会把ALL:后面的 做为 makefile 的终极目标

因此一般,我们都会写ALL

ALL:a.out

make file的写法:

命名只有两种,一种叫做makefile 一种叫做Makefile

一个规则,

目标:依赖条件

                (一个tab缩进)命令

hello:hello.c
        gcc hello.c -o hello

解释:

目标是生成hello 这个可执行文件

依赖条件的意思是:要生成hello这个目标文件,需要依赖于 hello.c这个文件

然后缩进,这个是语法格式要求

命令的意思是:怎么使用 hello.c生成hello这个目标文件

基本原则的原文:

        若想生成目标, 检查规则中的额依赖条件是否存在,如不存在,则寻找是否有规则用来生成该依赖文件。

好,我们把这段话从自己刚才写的例子理解一下:

上述我们写的时候 是目标是 hello ,依赖条件是hello.c

我们改写一下 先从hello.c生成 hello.o

然后从hello.o生成目标文件hello

hello:hello.o
        gcc hello.o -o hello

hello.o:hello.c
        gcc -c hello.c -o hello.o

hunandede@hunandede-virtual-machine:~/day03/makefilestudy$ ls
hello.c  makefile
hunandede@hunandede-virtual-machine:~/day03/makefilestudy$ make
gcc -c hello.c -o hello.o
gcc hello.o -o hello
hunandede@hunandede-virtual-machine:~/day03/makefilestudy$ 

1.学习这个之前,我们将昨天的部分整理过来并 按照g++的方法手动build 一下

文件内容如下,head 中存放.h文件

src 文件夹下放着所有的.cpp文件

g++ src/test.cpp src/addfunc.cpp src/devfunc.cpp src/mulfunc.cpp src/subfunc.cpp -o a.out -I ./head

如上,我们build 出来了一个 a.out文件,如下是执行 a.out文件

hunandede@hunandede-virtual-machine:~/day03/makefilestudy2$ ./a.out 
a+b = 15
a-b = 5
a*b = 50
a/b = 2

2. 改造成makefile 的写法

a.out:addfunc.o subfunc.o mulfunc.o devfunc.o test.o
	g++ addfunc.o subfunc.o mulfunc.o devfunc.o test.o -o a.out
addfunc.o:addfunc.cpp
	g++ -c addfunc.cpp -o addfunc.o -I../head

subfunc.o:subfunc.cpp
	g++ -c subfunc.cpp -o subfunc.o -I../head

mulfunc.o:mulfunc.cpp
	g++ -c mulfunc.cpp -o mulfunc.o -I../head

devfunc.o:devfunc.cpp
	g++ -c devfunc.cpp -o devfunc.o -I../head

test.o:test.cpp
	g++ -c test.cpp -o test.o -I../head

执行make 就会生成a.out文件,然后我们运行 a.out文件

hunandede@hunandede-virtual-machine:~/day03/makefilestudy2/src$ ./a.out 
a+b = 15
a-b = 5
a*b = 50
a/b = 2

 这里有一个问题:我们上面为什么要将所有的.c分开写,转成.o,然后再使用使用所有的.o生成 a.out呢? 直接 g++ addfunc.cpp subfunc.cpp mulfunc.cpp divfunc.cpp -o a.out 写起来不是更方便吗?

原因是 当addfunc.cpp的代码有改动后,重新build的时候,这么一行的写法会让所有的.cpp文件编译成.o,然后将所有的.o文件再链接成 a.out文件。

实际上只有 addfunc.cpp改动了,其他的都没有变化,让其他的跟着重新build出来自己的.o文件是很没有必要的。因此要分开写。

回顾 g++编译的四个阶段

预处理:头文件展开,宏替换,注释去掉

编译:检查语法错误,将c语言变成汇编语言,消耗时间和系统资源最多

汇编:将汇编语言变成 二进制指令

链接:数据段合并以及地址回填,将函数库中相应的代码组合到目标文件中

引申出的另一个问题:g++是如何知道addfunc.cpp有变化了,那就要看file 属性中的ctime了,changed time,当一旦发现ctime有变化,就会重新编译了。实际上应该是说 当addfunc.cpp的ctime比addfunc.o的时间晚,则会重新编译 addfunc.cpp

1.目标的时间必须晚于依赖条件的时间,否则,更新目录。

2.依赖条件如果不存在找寻新的规则去产生依赖。

新的问题:


看起来是可以完全fix此类问题,好,又有一个新问题,我们的需求变化了,增加了一个 模余.cpp文件,用来求余数的。

那么我们就要改动 makefile文件以支持,类似如下的写法,

虽然也可以实现功能,但是很笨拙

a.out:addfunc.o subfunc.o mulfunc.o devfunc.o moyufunc.o test.o
	g++ addfunc.o subfunc.o mulfunc.o devfunc.o test.o -o a.out
addfunc.o:addfunc.cpp
	g++ -c addfunc.cpp -o addfunc.o -I../head

subfunc.o:subfunc.cpp
	g++ -c subfunc.cpp -o subfunc.o -I../head

mulfunc.o:mulfunc.cpp
	g++ -c mulfunc.cpp -o mulfunc.o -I../head

devfunc.o:devfunc.cpp
	g++ -c devfunc.cpp -o devfunc.o -I../head

moyufunc.o:moyufunc.cpp
	g++ -c moyufunc.cpp -o moyufunc.o -I../head

test.o:test.cpp
	g++ -c test.cpp -o test.o -I../head

解决这样笨拙写法的方案是 使用两个函数,类似通配符

二个函数

wildcard  和 patsubst

wildcard :通配符,白搭牌的意思

patsubst: 是用来匹配和替换的。

src = $(wildcard *.cpp) 

src = $(wildcard *.cpp)    匹配当前工作目录下的所有.cpp文件, 将文件名组成列表,赋值给变量src
也就是说,在这一句执行完毕之后,src = addfunc.cpp subfunc.cpp mulfunc.cpp divfunc.cpp
解释:
$(wildcard *.c) 整个是函数调用, wildcard 是函数名,*.c 表示参数
整个函数调用完成后,会交给 src 这个变量, 脚本变量只有一种类型,字符类型
注意的是  wildcard 和 *.cpp 是有空格的。

obj = $(patsubst %.cpp,%.o, $(src))

obj = $(patsubst %.cpp,%.o, $(src))
将参数3中 ,包含参数1的部分,替换为参数2
$(src)表示将 src 中变量依次 取出来,src 中是 addfunc.cpp subfunc.cpp mulfunc.cpp divfunc.cpp
然后把src变量里所有后缀为.cpp的文件替换成.o
将addfunc.cpp替换成addfunc.o
将subfunc.cpp替换成subfunc.o
将mulfunc.cpp替换成mulfunc.o
将divfunc.cpp替换成divfunc.o
因此当 $(patsubst %.cpp,%.o, $(src))执行完毕后,
obj中的值是:addfunc.o subfunc.o mulfunc.o divfunc.o
有了这两个函数,makefile就能简化
但是这个简化程度 只能将 集体的.cpp  或者.c 或者.o 替换,还不能完全达到我们想要的结果,因此还要往后面学习三个自动变量的使用
src = $(wildcard *.cpp)     #src = addfunc.cpp, subfunc.cpp mulfunc.cpp devfunc.cpp test.cpp
obj = $(patsubst %.cpp, %.o, $(src))      #obj = addfunc.o subfunc.o mulfunc.o devfunc.o test.o

ALL:a.out

a.out:$(obj)
	g++ $(obj) -o a.out
addfunc.o:addfunc.cpp
	g++ -c addfunc.cpp -o addfunc.o -I../head

subfunc.o:subfunc.cpp
	g++ -c subfunc.cpp -o subfunc.o -I../head

mulfunc.o:mulfunc.cpp
	g++ -c mulfunc.cpp -o mulfunc.o -I../head

devfunc.o:devfunc.cpp
	g++ -c devfunc.cpp -o devfunc.o -I../head

test.o:test.cpp
	g++ -c test.cpp -o test.o -I../head

clean:
	-rm -rf $(obj) a.out


#a.out:addfunc.o subfunc.o mulfunc.o devfunc.o test.o
#	g++ addfunc.o subfunc.o mulfunc.o devfunc.o test.o -o a.out
#addfunc.o:addfunc.cpp
#	g++ -c addfunc.cpp -o addfunc.o -I../head

#subfunc.o:subfunc.cpp
#	g++ -c subfunc.cpp -o subfunc.o -I../head

#mulfunc.o:mulfunc.cpp
#	g++ -c mulfunc.cpp -o mulfunc.o -I../head

#devfunc.o:devfunc.cpp
#	g++ -c devfunc.cpp -o devfunc.o -I../head

#test.o:test.cpp
#	g++ -c test.cpp -o test.o -I../head

clean 清除不想要的文件

还有一个问题,我们每次build 出来的都有.o文件,实际上这个.o文件是中间文件,没啥用,

可以使用 clean指令删除这些不想要的.o文件,也可以将 a.out

clean:
        -rm -rf $(obj) a.out

使用时,先用 make clean -n,看一下要删除哪些东西,确认没有问题后,

再使用 make clean 真正的删除。

-rm 这个 -的意思是 即使这个文件不存在,也不会报错

三个自动变量

$@      在规则的命令中,表示规则中的目标,也就是说,只能出现在如下的“命令”中

目标:依赖条件

                (一个tab缩进)命令

$^         在规则的命令中,表示所有的依赖条件

$<        在规则的命令中,表示第一个依赖条件

如果将该变量应用在模式规则中,它可将依赖条件列表中的依赖条件,依次取出,套用模式规则。

那就在改一版

src = $(wildcard *.cpp)     #src = addfunc.cpp, subfunc.cpp mulfunc.cpp devfunc.cpp test.cpp
obj = $(patsubst %.cpp, %.o, $(src))      #obj = addfunc.o subfunc.o mulfunc.o devfunc.o test.o

ALL:a.out


a.out:$(obj)
	g++ $^ -o $@    #changed the 规则的命令中,只能是在命令行改动
addfunc.o:addfunc.cpp
	g++ -c $< -o $@ -I../head

subfunc.o:subfunc.cpp
	g++ -c $< -o $@ -I../head

mulfunc.o:mulfunc.cpp
	g++ -c $< -o $@ -I../head

devfunc.o:devfunc.cpp
	g++ -c $< -o $@ -I../head

test.o:test.cpp
	g++ -c $< -o $@ -I../head

clean:
	-rm -rf $(obj) a.out



#a.out:$(obj)
#	g++ $(obj) -o a.out
#addfunc.o:addfunc.cpp
#	g++ -c addfunc.cpp -o addfunc.o -I../head

#subfunc.o:subfunc.cpp
#	g++ -c subfunc.cpp -o subfunc.o -I../head

#mulfunc.o:mulfunc.cpp
#	g++ -c mulfunc.cpp -o mulfunc.o -I../head

#devfunc.o:devfunc.cpp
#	g++ -c devfunc.cpp -o devfunc.o -I../head

#test.o:test.cpp
#	g++ -c test.cpp -o test.o -I../head

#clean:
#	-rm -rf $(obj) a.out


#a.out:addfunc.o subfunc.o mulfunc.o devfunc.o test.o
#	g++ addfunc.o subfunc.o mulfunc.o devfunc.o test.o -o a.out
#addfunc.o:addfunc.cpp
#	g++ -c addfunc.cpp -o addfunc.o -I../head

#subfunc.o:subfunc.cpp
#	g++ -c subfunc.cpp -o subfunc.o -I../head

#mulfunc.o:mulfunc.cpp
#	g++ -c mulfunc.cpp -o mulfunc.o -I../head

#devfunc.o:devfunc.cpp
#	g++ -c devfunc.cpp -o devfunc.o -I../head

#test.o:test.cpp
#	g++ -c test.cpp -o test.o -I../head

4.模式规则

我们发现上面的代码是有些是很相似的

#都是
%o:%.cpp

        g++ -c $< -o $@ -I../head

addfunc.o:addfunc.cpp
	g++ -c $< -o $@ -I../head

subfunc.o:subfunc.cpp
	g++ -c $< -o $@ -I../head

mulfunc.o:mulfunc.cpp
	g++ -c $< -o $@ -I../head

devfunc.o:devfunc.cpp
	g++ -c $< -o $@ -I../head

test.o:test.cpp
	g++ -c $< -o $@ -I../head

#都是
%o:%.cpp
    g++ -c $< -o $@ -I../head

#因此可以直接替换,这个就是规则模式

5.还有问题:模式规则的疑问fix-使用静态模式规则

我们前面通过模式规则将.cpp变成.o

那么如果我们有些.cpp不想变成.o文件呢?

或者说我们还有一些c文件也要变成.o文件呢?

静态模式规则就是用来fix上述问题的。

obj2 = main.c func1.c func2.c
obj1 = aa.cpp bb.cpp cc.cpp

$(obj1):%o:%.cpp

        g++ -c $< -o $@ -I../head

$(obj2):%o:%.c

        g++ -c $< -o $@ -I../head

因此可以再改动一版

src = $(wildcard *.cpp)     #src = addfunc.cpp, subfunc.cpp mulfunc.cpp devfunc.cpp test.cpp
obj = $(patsubst %.cpp, %.o, $(src))      #obj = addfunc.o subfunc.o mulfunc.o devfunc.o test.o

ALL:a.out


a.out:$(obj)
	g++ $^ -o $@    #changed the 规则的命令中,只能命令行

%.o:%.cpp
	g++ -c $< -o $@ -I../head

#addfunc.o:addfunc.cpp
#	g++ -c $< -o $@ -I../head

#subfunc.o:subfunc.cpp
#	g++ -c $< -o $@ -I../head

#mulfunc.o:mulfunc.cpp
#	g++ -c $< -o $@ -I../head

#devfunc.o:devfunc.cpp
#	g++ -c $< -o $@ -I../head

#test.o:test.cpp
#	g++ -c $< -o $@ -I../head

clean:
	-rm -rf $(obj) a.out



#a.out:$(obj)
#	g++ $(obj) -o a.out
#addfunc.o:addfunc.cpp
#	g++ -c addfunc.cpp -o addfunc.o -I../head

#subfunc.o:subfunc.cpp
#	g++ -c subfunc.cpp -o subfunc.o -I../head

#mulfunc.o:mulfunc.cpp
#	g++ -c mulfunc.cpp -o mulfunc.o -I../head

#devfunc.o:devfunc.cpp
#	g++ -c devfunc.cpp -o devfunc.o -I../head

#test.o:test.cpp
#	g++ -c test.cpp -o test.o -I../head

#clean:
#	-rm -rf $(obj) a.out


#a.out:addfunc.o subfunc.o mulfunc.o devfunc.o test.o
#	g++ addfunc.o subfunc.o mulfunc.o devfunc.o test.o -o a.out
#addfunc.o:addfunc.cpp
#	g++ -c addfunc.cpp -o addfunc.o -I../head

#subfunc.o:subfunc.cpp
#	g++ -c subfunc.cpp -o subfunc.o -I../head

#mulfunc.o:mulfunc.cpp
#	g++ -c mulfunc.cpp -o mulfunc.o -I../head

#devfunc.o:devfunc.cpp
#	g++ -c devfunc.cpp -o devfunc.o -I../head

#test.o:test.cpp
#	g++ -c test.cpp -o test.o -I../head

删除各个版本演化注释的,就变成下面的样子了

src = $(wildcard *.cpp)     #src = addfunc.cpp, subfunc.cpp mulfunc.cpp devfunc.cpp test.cpp
obj = $(patsubst %.cpp, %.o, $(src))      #obj = addfunc.o subfunc.o mulfunc.o devfunc.o test.o

ALL:a.out


a.out:$(obj)
	g++ $^ -o $@    #changed the 规则的命令中,只能命令行

%.o:%.cpp
	g++ -c $< -o $@ -I../head

clean:
	-rm -rf $(obj) a.out

6. makefile脚本的运行

1.直接make 就会执行makefile 中的所有指令

2.使用make -n 不会真的执行指令,会将指令显示出来

2.使用make clean -n 查看要清除的文件

3.使用make clean 真正清除文件

7.make执行时候的问题

从上述的学习知道,我们会在makefile 中写一个

ALL:a.out


clean:
	-rm -rf $(obj) a.out

如果这时候我们当前文件下,还有一个 clean的文件,

再使用make clean的时候就会有问题。

因此我们还有改动 makefile文件,写一个伪目标

.PHONY: clean ALL 这句话的意思是:即使当前文件夹下有 clean的文件,或者有ALL的文件,会认为clean文件和ALL文件是伪目标。不会执行真正的文件,而是执行make 命令参数。例如:make clean

src = $(wildcard *.cpp)     #src = addfunc.cpp, subfunc.cpp mulfunc.cpp devfunc.cpp test.cpp
obj = $(patsubst %.cpp, %.o, $(src))      #obj = addfunc.o subfunc.o mulfunc.o devfunc.o test.o

ALL:a.out


a.out:$(obj)
	g++ $^ -o $@    #changed the 规则的命令中,只能命令行

%.o:%.cpp
	g++ -c $< -o $@ -I../head

clean:
	-rm -rf $(obj) a.out

.PHONY: clean ALL

8.优化,可以将-g -Wall -I 作为参数加进去

src = $(wildcard *.cpp)
obj = $(patsubst %.cpp, %.o, $(src))

ALL:a.out

myargs = -g -Wall -I../head

a.out:$(obj)
	g++ $^ -o $@ ${myargs} 

%.o:%.cpp
	g++ -c $< -o $@ ${myargs}

clean:
	-rm -rf $(obj) a.out

.PHONY: clean ALL


 

9.练习 1

要求 inc 目录下放置.h文件

obj目录下放置生成的.obj文件

src目录下放置.cpp 文件

最终生成的 a.out可执行文件和makefile文件在同一级目录

写出makefile文件

src1 = $(wildcard ./src/*.cpp)   #这时候 src1 = ./src/addfunc.cpp ./src/subfunc.cpp ......
obj = $(patsubst ./src/%.cpp, ./obj/%.o, $(src1))  

#这里要注意 将参数3中 ,包含参数1的部分,替换为参数2 ,这时候参数3取出来的值是 ./src/addfunc.cpp
#因此需要将 patsubst %.cpp 换成 .src/%.cpp, 将第二个参数%.o改成 ./obj/%o, 
#这样 % 才能代表同样的部分,也就是文件名的部分, obj的值就是 ./obj/addfunc.o ./obj/subfunc.o  ......



ALL:a.out

myargs = -g -Wall -I./inc

a.out:$(obj)
	g++ $^ -o $@ ${myargs}

./obj/%.o : ./src/%.cpp
	g++ -c $< -o $@ ${myargs}


clean:
	-rm -rf $(obj) a.out

.PHONY: clean ALL

10.练习 2 ,本地有多个 main程序,一键生成

假设有a.cpp, b.cpp, c.cpp 每个.cpp文件中都有main函数,

我们的目标是实现

g++ a.cpp -o a

g++ b.cpp -o b

g++ c.cpp -o c

src = $(wildcard *.cpp)

target = $(patsubst %.cpp, %, $(src))

ALL: $(target)

%:%cpp
	gcc &< -o $@

clean:
	-rm -rf $(target)

.PHONY: clean ALL

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

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

相关文章

服务器被黑该如何查找入侵痕迹以及如何防御攻击

当公司的网站服务器被黑&#xff0c;被入侵导致整个网站&#xff0c;以及业务系统瘫痪&#xff0c;给企业带来的损失无法估量&#xff0c;但是当发生服务器被攻击的情况&#xff0c;作为服务器的维护人员应当在第一时间做好安全响应&#xff0c;对服务器以及网站应以最快的时间…

程序环境和预处理(1)

文章目录 目录1. 程序的翻译环境和执行环境2. 详解编译链接2.1 翻译环境2.2 编译本身也分为几个阶段2.3 运行环境 3. 预处理详解3.1 预定义符号3.2 #define3.2.1 #define 定义标识符3.2.2 #define 定义宏3.2.3 #define 替换规则3.2.4 #和##3.2.5 带副作用的宏参数3.2.6 宏和函数…

HAT论文详解:Activating More Pixels in Image Super-Resolution Transformer

code&#xff1a;https://github.com/XPixelGroup/HAT paper: https://arxiv.org/abs/2309.05239 1. 概述 本文是对Swinir的改进&#xff0c;目前很多图像超分Benchmark的SOTA。相对于SwinIR的改进主要有三个地方&#xff1a;1. 引入Channel Attention,以获得更好的全局能力&…

【Linux】 login命令使用

login命令 在 Linux 中用于创建一个新的会话&#xff0c;并在新会话中登录用户。这个命令通常在终端中自动执行&#xff0c;当你打开一个新的终端会话或者通过 SSH 远程连接到 Linux 服务器时。 在命令后面附加欲登入的用户名称&#xff0c;它会直接询问密码&#xff0c;等待…

探索水下低光照图像检测性能,基于YOLOv3全系列【yolov3tiny/yolov3/yolov3spp】参数模型开发构建海底生物检测识别分析系统

海底这类特殊数据场景下的检测模型开发相对来说比较少&#xff0c;在前面的博文中也有一些涉及&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《尝试探索水下目标检测&#xff0c;基于yolov5轻量级系列模型n/s/m开发构建海底生物检测系统》 《基于YOLOv5C3CBAMCBA…

Element table 实现表格行、列拖拽功能

安装包 npm install sortablejs --save <template><div class"draggable" style"padding: 20px"><el-table row-key"id" :data"tableData" style"width: 100%" border><el-table-columnv-for"(it…

【Linux】 faillock 命令使用

faillock 命令 faillock 命令是 PAM (Pluggable Authentication Modules) 的一部分&#xff0c;它被设计用来跟踪失败的登录尝试&#xff0c;并在连续失败尝试超过某个阈值时锁定账户。这个功能可以帮助系统管理员识别和防止暴力破解攻击。当一个用户连续多次输入错误的密码后&…

如何开发自己的npm包并上传到npm官网可以下载

目录 搭建文件结构 开始编写 发布到npm 如何下载我们发布的npm包 搭建文件结构 先创建新文件夹,按照下面的样子布局 .├── README.md //说明文档 ├── index.js //主入口 ├── lib //功能文件 └── tests //测试用例 然后再此根目录下初始化package包 npm init…

Cartographer 构建约束优化问题

计算优化的思路&#xff0c;需要两种坐标变换&#xff0c;用两种坐标变化的残差求解。 第一种残差 将节点与子图原点在global坐标系下的相对位姿与约束的差值作为残差项 第一种坐标变换&#xff1a;节点与子图原点在global坐标系下的坐标变换 第二种坐标变换&#xff1a;子图内…

NXP实战笔记(八):S32K3xx基于RTD-SDK在S32DS上配置LCU实现ABZ解码

目录 1、概述 2、SDK配置 2.1、IO配置 2.2、TRGMUX配置 2.3、LCU配置 2.4、Trgmux配置 2.5、Emios配置 2.6、代码实现 1、概述 碰到光电编码器、磁编码器等,有时候传出来的位置信息为ABZ的方式,在S32K3里面通过TRGMUX、LCU、Emios结合的方式可以实现ABZ解码。 官方…

【Pytorch】从MoCo看无监督对比学习;从SupCon看有监督对比学习

目录 无监督对比学习&#xff1a;Moco文章内容理解代码解释 有监督对比学习&#xff1a;Supervised Contrastive Learning文章内容理解 无监督对比学习&#xff1a;Moco 文章内容理解 以下内容全部来自于&#xff1a;自监督学习-MoCo-论文笔记. 侵删 论文&#xff1a;Momentu…

vue : 无法加载文件 C:\Program Files\nodejs\node_global\vue.ps1,因为在此系统上禁止运行脚本。

解决方法&#xff1a; 打开PowerShell&#xff0c;在命令框输入set-ExecutionPolicy RemoteSigned 在PowerShell中输入会出现如下图&#xff0c;输入y即可。

【MATLAB】 RLMD信号分解+FFT傅里叶频谱变换组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 展示出图效果 1 RLMD分解算法 RLMD&#xff08;Robust Local Mode Decomposition&#xff09;是一种鲁棒的局部模态分解方法。它是通过在局部区间内对信号进行多项式拟合&#xff0c;提取局部特征&#xff0c;进而分解信…

【Vuforia+Unity】AR07-实现识别条码、二维码内容功能(Barcode Scanner)

Barcode Scanner in Unity | Vuforia Library官方教程,写的很详细,本教程主要参考对象! 主要实现扫描生活中常见的二维码,然后弹出二维码链接,当然我们也可以再次回调自定义函数,弹出数字内容,AR内容效果! 支持的二维码: 局限性 条码扫描组件还定义检测和跟踪的条形…

2024年2月前端资讯动态:JSR新仓库革新及Set方法等全新特性

2024年2月前端技术领域再次迎来了一系列激动人心的更新和进展。无论是新兴的包仓库JSR&#xff0c;还是JavaScript提案中的Set方法、Array.prototype.with()的加入&#xff0c;都预示着前端开发的未来将更加灵活和强大。本文将为您详细介绍这些技术的最新动态&#xff0c;帮助您…

【电路笔记】-RC放电电路

RC放电电路 文章目录 RC放电电路1、概述2、RC放电电路3、RC放电电路示例当电压源从完全充电的 RC 电路中移除时,电容器 C 将通过电阻 R 放电。 1、概述 RC 放电电路利用电阻器-电容器组合的固有 RC 时间常数以指数衰减率对电容器进行放电。 在之前的 RC 充电电路教程中,我们…

挑战30天学完Python:Day18 正则表达式

&#x1f4d8; Day 18 &#x1f389; 本系列为Python基础学习&#xff0c;原稿来源于 30-Days-Of-Python 英文项目&#xff0c;大奇主要是对其本地化翻译、逐条验证和补充&#xff0c;想通过30天完成正儿八经的系统化实践。此系列适合零基础同学&#xff0c;或仅了解Python一点…

【区块链】联盟链

区块链中的联盟链 写在最前面**FAQs** 联盟链&#xff1a;区块链技术的新兴力量**联盟链的定义****联盟链的技术架构**共识机制智能合约加密技术身份认证 **联盟链的特点**高效性安全性可控性隐私保护 **联盟链的应用场景****金融服务****供应链管理****身份验证****跨境支付**…

2024云服务器ECS_云主机_服务器托管_e实例-阿里云

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如ECS经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云服务器网al…

【风格迁移】CAST:对比学习,从图像特征而非其二阶统计量(Gram矩阵)中学习风格

CAST&#xff1a;对比学习&#xff0c;从图像特征而非其二阶统计量&#xff08;Gram矩阵&#xff09;中学习风格 提出背景5 why 分析5 so分析 CAST 框架多层风格投影器领域增强模块生成网络 效果对比 StyleGAN 提出背景 论文&#xff1a;https://arxiv.org/pdf/2205.09542.pdf…