【嵌入式】Makefile 学习笔记记录 | 嵌入式Linux

文章目录

  • 前言
  • 一、Makefile的引入——最简单的gcc编译过程
  • 二、Makefile的规则
  • 三、Makefile的语法
    • 3.1、通配符
    • 3.2、假想目标 .phony
    • 3.3、即时变量 延时变量
  • 四、Makefile的函数
    • 4.1、foreach
    • 4.2、filter
    • 4.3、wildcard
    • 4.4、patsubst
  • 五、Makefile升级
    • 5.1、包含头文件在内的依赖关系(自动生成依赖文件)
    • 5.2、添加CFLAGS
  • 六、通用Makefile模板


前言

开发板平台:飞凌嵌入式ElfBoard ELF-1
参考视频和资料:飞凌嵌入式ElfBoard ELF-1软件学习书册
韦东山:https://www.bilibili.com/video/BV1kk4y117Tu?p=6&vd_source=3018264d4331e8fc267f9d68c24ee20f

一、Makefile的引入——最简单的gcc编译过程

keil,mdk,avr这些工具全自动编译的内部机制依然是makefile

这里我们先随便写两个C文件(a.c 和b.c),用最传统的gcc编译一下:

a.c:

#include <stdio.h>
void funB();
int main() {funB();return 0;
}

b.c:

#include <stdio.h>
void funB() {printf("hello B!\n");
}

然后我们上传到虚拟机上进行编译:

gcc -o test a.c  b.c

然后执行

./test

在这里插入图片描述
从a.c b.c到可执行文件test经历了什么?:
总的来说就是四步:预处理,编译,汇编,链接(一般来说前三步统称为编译)
a.c ->a.s->a.o
b.c ->b.s->b.o
最后两个.o链接在一起生成可执行文件test

我们可以在gcc命令后加上 -v看到编译链接的完整过程:

gcc -o test a.c  b.c -v

具体内容很多,就不一一截图了:
在这里插入图片描述
这样gcc有个很明显的缺点:
不论a.c b.c有没有被更改过,每次gcc都会重新编译链接所有的C文件。有的时候我们只修改了很小一部分的C文件,但此时我们gcc会全部重新编译,这很耽误时间。

makefile就能解决这个问题。
它可以把刚刚gcc这个过程解构成一系列小的编译过程:

gcc -c -o a.o a.c
gcc -c -o b.o b.c
gcc -o test  a.o b.o

这三句命令的含义如下:

gcc -c -o a.o a.c:这个命令使用 GCC 编译器将源文件 a.c 编译成目标文件 a.o。具体解释如下:
-c 选项表示只进行编译,而不进行链接,生成目标文件。
-o a.o 选项指定输出文件的名称为 a.o。
a.c 是源文件的名称。

gcc -c -o b.o b.c:这个命令与第一条类似,将源文件 b.c 编译成目标文件 b.o。

gcc -o test a.o b.o:这个命令使用 GCC 编译器将目标文件 a.o 和 b.o 进行链接,生成一个名为 test 的可执行文件。
-o test 选项指定输出文件的名称为 test。
a.o b.o 是链接的目标文件。

综合起来,这三条命令用于分别编译两个源文件 a.c 和 b.c,然后将生成的目标文件 a.o 和 b.o 链接在一起,形成一个名为 test 的可执行文件。
makefile如何自己的这些文件被修改了?:
在第一行 判断到a.c比a.o新,就说明a.c被更新过了,就可以重新编译
在第二行 判断到b.c比b.o新,就说明b.c被更新过了,就可以重新编译
在第三行 判断到a.o b.o比test新,就说明a.o b.o被更新过了,就可以重新编译

二、Makefile的规则

makefile的基本语法格式为:


目标文件:依赖文件
TAB 命令


当依赖比目标的时候 or 该目标文件直接不存在的时候,就会执行命令

我们在刚刚的文件夹中新建一个makefile:
在这里插入图片描述
然后执行make两此看一下效果:

make
make

在这里插入图片描述
第一次Make正确得运行了我们makefile里面写的所有语句
第二次make因为没有检测到依赖项更新,所以并没有重新编译

我们再做一个小实验,即只修改a.c ,只修改b.c 以及同时修改a.c和b.c再分别执行make的效果:
在这里插入图片描述
可以看到,我们修改了啥,make时也只会重新执行依赖项变动的语句,没有修改的部分不会重新执行命令。
(touch 命令是用来更新文件的访问和修改时间戳的工具,如果文件不存在,则会创建一个空白文件。它不会修改文件的内容,只是更新文件的元数据。所以,touch 命令不会改变文件的内容,只是改变文件的时间戳相当于变相修改了文件

三、Makefile的语法

3.1、通配符

我们再增加一个c.c文件,里面有一个函数func():

#include <stdio.h>
void funC() {printf("hello C!\n");
}

再把a.c里的内容改一下,把函数func加上去:

#include <stdio.h>
void funB();
void funC();
int main() {funB();funC();return 0;
}

再使用通配符对makefile里面的语句进行一定的修改:
在这里插入图片描述
1)$^表示所有的依赖文件
2)使用 $< 表示第一个依赖文件(源文件),使用 $@ 表示目标文件
这样就可以把gcc -o -c a.o a.c 和gcc -o -c b.o b.c合并成一句话了

我们在虚拟机上看一下效果:

在这里插入图片描述
这里make没啥问题,正常工作了。

3.2、假想目标 .phony

phony,英语单词,主要用作形容词、名词,作形容词时译为"假的,欺骗的"
我们首先补一下make clean的内容 我们修改一下makefile中的内容:
在这里插入图片描述
增加了一句话:

clean:rm *.o test

Makefile 中还包含了一个 clean 目标,用于清理生成的目标文件和可执行文件:
当执行 make clean 时,它将删除当前目录下的所有 .o 文件和 test 可执行文件

我们上虚拟机实验一下:
在这里插入图片描述
发现所有的.o文件和可执行文件test均被清除了,这就是make clean的作用

在讲完clean之后,正式引出我们的makefile的一个语法:


make [目标]
比如说make clean,就会寻找makefile里面名为clean的目标,执行其tab后的命令
如果make后没有加东西(直接就是make),那么系统会默认自动执行第一个目标的命令,在上文中,就会自动执行test目标的命令。


在这个规则下有一个bug,就是遇到同名文件的情况(这里以clean同名文件为例子),**因为在makefile里并没有clean的依赖项文件。**之前是因为没有clean这个东西,所以执行会很顺利。
在这里插入图片描述

我们在虚拟机上新建一个名为clean的文件,我们先make,再执行make clean。此时根据makefile的规则,系统没有检测到clean发生改变(因为存在同名文件clean),那么执行make clean时就不会正确执行:
在这里插入图片描述
解决办法:我们把clean设置为假想目标就能解决这个问题
我们稍微改一下makefile:
在这里插入图片描述
这里使用了 .PHONY 目标,它告诉 Make 这个目标不对应真实的文件名。这样做的目的是防止与同名的实际文件冲突,同时确保即使存在同名文件,make clean 也能正常执行。
这回我们再实验一下就对了:
在这里插入图片描述

3.3、即时变量 延时变量

我们写一个新的makefile:
在这里插入图片描述
这个 Makefile 定义了两个变量 A 和 B,然后在 all 目标中使用了这两个变量。以下是中文解释:

A := abc 表示定义了一个变量 A,其值为 “abc”。:= 是一种赋值方式,表示覆盖先前的值。(即刻确定)
B = 123 表示定义了一个变量 B,其值为 “123”。= 也是一种赋值方式,但是它是延迟赋值,即在使用变量时才会展开。(延迟确定

all 目标中使用了 echo $(A) 和 echo $ (B) 分别输出变量 A 和 B 的值。在 Makefile 中,$() 用于引用变量的值echo 是一个在命令行中常用的命令,用于将文本输出到标准输出设备(通常是终端)。在类Unix系统(如Linux)和类似的命令行环境中,echo 命令通常用于显示文本。

我们make一下看看效果:
在这里插入图片描述
我们可以在echo前面加上@ :
在这里插入图片描述
这样就不会打印命令本身了:
在这里插入图片描述
到这里我们还看不出即时变量和延时变量的区别,我们再makefile添一些代码:
在这里插入图片描述
A是即可确定,但此时C还并没被赋值,所以这时会打印空
B是使用时才确定,所以不会为空
我们实验一下:
在这里插入图片描述
我们如果更改C=abc的位置呢:
在这里插入图片描述
最后结果还是不影响:(即C位置不影响B,系统会对makefile整体进行分析)

在这里插入图片描述
最后我们再介绍两种符号:+= ?=
在makefile里我们做如下更改:
在这里插入图片描述
make一下看看效果:
在这里插入图片描述
1)+= 运算符:用于追加值到变量。使用 += 时,它会将右侧的值追加到已经存在的变量值的末尾。如果变量之前未定义,则行为类似于简单的赋值。
2)?= 运算符:用于给变量赋值,但仅在该变量之前未定义时才赋值。使用 ?= 时,它会检查变量是否已经定义,如果已定义则不进行赋值,否则将变量赋予指定的默认值。

总结:
1):= 即时变量
2)= 延时变量
3)?=延时变量 是第一次定义才起效果
4)+= 附加 它是即时变量还是延时变量 取决于前面

四、Makefile的函数

4.1、foreach

foreach 是GNU Make中的一个函数,用于进行循环迭代。其基本语法如下:

$(foreach var, list, text)

var: 循环中的临时变量,表示每次迭代中的当前元素。

list: 要迭代的列表,可以是以空格分隔的多个元素。

text: 在每次迭代中对var进行操作的文本块。

我们写一个新的makefile:
在这里插入图片描述
A=a b c: 定义了一个变量A,包含三个元素a、b和c。
B=$(foreach f, $(A), $(f).o): 使用foreach循环,将A中的每个元素加上.o后缀,并将结果存储到变量B中。
all:: 定义了一个目标规则名为all。@echo B = $(B): 在执行all目标时,打印出变量B的值。
最后结果:
在这里插入图片描述

4.2、filter

filter 是GNU Make中的一个函数,用于从列表中筛选出符合指定条件的元素。其基本语法如下:

$(filter pattern..., text)

pattern…: 一个或多个模式,用于指定筛选条件。可以包含通配符 %。
text: 要进行筛选的文本块,通常是一个以空格分隔的元素列表。
filter函数会返回text中符合给定模式的元素列表。模式之间使用空格分隔。

filter函数还支持反向操作,使用filter-out可以筛选出不符合指定条件的元素。例如:

C = $(filter-out a%, $(A))

在这个例子中,匹配A中不以字母’a’开头的元素。

我们写一个新的Makefile:
在这里插入图片描述

C = a b c d/: 定义了一个变量C,包含四个元素a、b、c和d/。
D = $(filter %/, $©): 使用filter函数,从C中筛选出以’/'结尾的元素,存储到变量D中。在这个例子中,D的值为d/。
E = $(filter-out %/, $©): 使用filter-out函数,从C中筛选出不以’/'结尾的元素,存储到变量E中。在这个例子中,E的值为a b c。

最后结果:

在这里插入图片描述

4.3、wildcard

wildcard 是 GNU Make 中的一个函数,用于匹配文件名模式,返回匹配到的文件列表。其基本语法如下:

$(wildcard pattern)

pattern: 文件名模式,可以包含通配符 * 和 ?。
wildcard 函数会返回符合指定文件名模式的文件列表。通常,这个函数用于获取文件列表并将其赋值给一个变量,以便在 Makefile 中进一步处理这些文件。
我们写一个新的makefile:
请添加图片描述
files=$(wildcard *.c):使用 wildcard 函数匹配当前目录下所有以 .c 结尾的文件,并将结果存储到变量 files 中。
最后结果:
在这里插入图片描述

扩展应用:可以用检查目录下面哪些文件是真实存在的
请添加图片描述
定义了一个变量 files2 包含了一组源文件名,然后使用 wildcard 函数来获取这些文件的实际存在的文件列表并存储在变量 files3 中。(注意d.c e.c是不存在的)
最后结果:
在这里插入图片描述

4.4、patsubst

patsubst 是在 Makefile 中用来替换模式的函数之一。它用于将一个字符串中符合指定模式的部分替换成另一个模式。基本语法是:

$(patsubst pattern,replacement,text)

pattern 是要匹配的模式,可以包含 % 通配符,表示零个或多个字符。
replacement 是替换的模式。
text 是要进行替换操作的原始文本。

我们改一下makefile:
在这里插入图片描述
Makefile 中,定义了一个变量 files2 包含了一组源文件名,其中包含一个不是以 .c 结尾的文件 abc。接着,使用 patsubst 函数将每个源文件名的扩展名从 .c 替换为 .d,并将结果存储在变量 dep_files 中。

最后结果:
在这里插入图片描述

五、Makefile升级

5.1、包含头文件在内的依赖关系(自动生成依赖文件)

我们使用前面一样的程序来进行实验:
a.c:

#include <stdio.h>
void funB();
void funC();
int main() {funB();funC();return 0;
}

b.c:

#include <stdio.h>
void funB() {printf("hello B!\n");}

c.c:(进行了一点点修改)

#include <stdio.h>
#include "c.h"
void funC() {printf("This is C=%d\n",C);
}

新建一个c.h

#define C 1 

然后我们make加执行一下:
在这里插入图片描述
在这里插入图片描述
我们这里做一个小小的改动,把头文件中define的数从1改为2:

#define C 2 

然后我们再make一下看看效果:
在这里插入图片描述
我们可以看到make并没有顺利执行,而且C依然为1 ,说明还是有点小问题

那这是因为什么原因导致的呢:?
因为我们的c.c是依赖于c.h的,但是makefile中并没有把这种依赖关系写出来,所以makefile也不知道c.h更新了。

我们再makefile中重新添加了:

c.o:c.c c.h

在这里插入图片描述
然后我们再make一下就对了:
请添加图片描述
但是这样做是不可能的,在大型项目里面,我们每一个C文件几乎都有头文件,我们不可能手动把这些头文件的依赖关系一行行在makefile全部都写出来,我们需要自动去生成这些规则。


在讲解今天的正式内容前,我们先介绍三个查看依赖关系的命令:

gcc -M c.c

上述命令会使用 gcc 编译器并使用 -M 选项来生成 c.c 源文件的依赖关系,是立刻打印出来

请添加图片描述

gcc -M -MF c.d c.c

这个命令也会生成 c.c 源文件的依赖关系,但是通过 -MF c.d 选项指定了输出文件为 c.d。这意味着生成的依赖关系将被保存到 c.d 文件中,而不是输出到标准输出流。
在这里插入图片描述

gcc -c -o c.o c.c -MD -MF c.d

这个命令用于编译 c.c 源文件为目标文件 c.o。参数 -c 表示编译成目标文件,-o c.o 指定输出文件为 c.o。-MD 选项用于生成 .d 文件,-MF c.d 则指定生成的依赖关系文件为 c.d。这意味着除了生成目标文件 c.o 外,还会生成一个描述依赖关系的文件 c.d。
在这里插入图片描述
按照我们刚刚介绍的gcc依赖关系规则,我们修改一下makefile:
在这里插入图片描述
在这里插入图片描述
(ls 命令用于列出目录中的文件和子目录。而 ls -a 命令也会列出目录中所有的文件和子目录,包括以 . 开头的隐藏文件或隐藏目录,这些文件或目录在普通的 ls 命令中是不可见的。)

从这里我们可以看到这些依赖关系被自动生成出来了
刚刚makefile里的这句话就可以不用写了:

c.o:c.c c.h

我们再改一下makefile:
在这里插入图片描述
这一行使用了 Makefile 中的函数 patsubst,它用于替换模式。具体来说,% 是一个通配符,表示每个目标文件名。 ( p a t s u b s t (patsubst %,.%.d, (patsubst(objs)) 的作用是将目标文件列表中的每个目标文件名(a.o, b.o, c.o)替换成相应的依赖关系文件名(.a.o.d, .b.o.d, .c.o.d)。
在这里插入图片描述
可以看到我们的依赖文件已经被生成出来了。

接下来我们再改一改,把这些检测到的依赖文件包含进去:
在这里插入图片描述

objs=a.o b.o c.o
dep_files:=$(patsubst %,.%.d,$(objs))
dep_files:=$(wildcard $(dep_files))

这里定义了目标文件列表 objs 和依赖关系文件列表 dep_files。使用 patsubst 函数将目标文件列表转换为相应的依赖关系文件列表,然后通过 wildcard 函数获取实际存在的依赖关系文件。

ifneq ($(dep_files),)
include $(dep_files)
endif

这里使用条件语句检查是否存在依赖关系文件列表 dep_files,如果存在,则通过 include 关键字包含这些依赖关系文件。这样,Make 就能够了解源文件之间的依赖关系,从而在需要重新编译时执行相应的规则。

我们这时候试一下修改c.h里的宏定义如下:

#define C 3 

这时候我们再make就不会再出现之前的情况了:即宏定义改了make之后打印出来依然不变的情况
最后结果:
在这里插入图片描述
我们可以看到改为了3,make后就自动识别了头文件的依赖关系,打印出来了3,实现了我们最初的目标:自动识别依赖关系(自动生成依赖文件)。

5.2、添加CFLAGS

我们在makefile里添加几条命令:
在这里插入图片描述
CFLAGS=-Werror 设置了一个编译选项,即启用了 -Werror。这个选项的含义是将所有警告视为错误,即编译过程中如果产生了任何警告,就会导致编译失败。这样做的目的是强制要求代码中不允许存在任何警告,以确保代码的质量和稳定性。

CFLAGS 是一个用于存储传递给 C 编译器的额外参数和标志的 Makefile 变量。这些参数和标志可以影响编译的行为,例如警告级别、优化选项、头文件路径等 在 Makefile 中使用 CFLAGS 变量有助于集中管理编译选项,使得构建过程更加灵活和易于维护。

当你设置 CFLAGS 时,可以包含各种编译器选项,这些选项会影响代码的编译和生成。以下是一些常见的 CFLAGS 选项的例子:

启用调试信息:

CFLAGS = -g

这个选项启用了编译器生成的调试信息,有助于在调试阶段中进行源代码级别的调试。

优化级别:

CFLAGS = -O2

这个选项启用了优化级别 2,以提高生成代码的运行性能。可选的优化级别包括 -O0(无优化)、-O1、-O2、-O3 等。

指定头文件搜索路径:

CFLAGS = -I/path/to/include

这个选项指定了编译器在搜索头文件时要查找的路径。

定义宏:

CFLAGS = -DDEBUG

这个选项定义了一个名为 DEBUG 的宏,可以在源代码中使用条件编译。

关闭某些警告:

CFLAGS = -Wno-unused-variable

这个选项关闭了关于未使用变量的警告。

启用全部警告:

CFLAGS = -Wall -Wextra

这个选项启用了大多数可用的警告,帮助开发者发现潜在的问题。

指定目标架构:

CFLAGS = -march=native

这个选项根据编译运行代码的计算机的架构进行优化。

来个实际点的makefile例子:

CC = gcc
CFLAGS = -g# 目标文件
TARGET = my_program# 源文件
SRC = main.call: $(TARGET)$(TARGET): $(SRC)$(CC) $(CFLAGS) -o $(TARGET) $(SRC)clean:rm -f $(TARGET)

在这个例子中:

CC 定义了编译器的可执行文件(gcc)。
CFLAGS 包含了编译器选项 -g,表示启用调试信息。
TARGET 定义了目标文件的名称为 my_program。
SRC 定义了源文件的名称为 main.c。

Makefile 中的规则:
all 是默认目标,它依赖于 $(TARGET),当你运行 make 时,它将编译生成目标文件。
$(TARGET) 的规则指定了如何生成目标文件。在这里,它使用 gcc 编译器,传递了 CFLAGS 和源文件,生成可执行文件 my_program。
clean 规则用于清理生成的文件,执行 make clean 将删除可执行文件。

六、通用Makefile模板

这个意思就是找一个经典的makefile模板 以后要写自己的makefile就在这个基础上改就行了

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为认证 | 这门HCIE认证正式发布!

华为认证openEuler专家HCIE-openEuler V1.0&#xff08;中文版&#xff09;自2023年12月29日起&#xff0c;正式在中国区发布。 01 发布概述 基于“平台生态”战略&#xff0c;围绕“云-管-端”协同的新ICT技术架构&#xff0c;华为公司打造了覆盖ICT领域的认证体系&#xff0…

会stm32有机会进大公司吗?

今日话题&#xff0c;会stm32有机会进大公司吗&#xff1f;我本科期间参与了飞思卡尔和电赛等比赛&#xff0c;使用过多种单片机&#xff0c;但渐渐发现单片机只是其中的一小部分。不要过分迷恋所谓的单片机基础和技巧&#xff0c;更值得深入研究的是C语言。如果你对此感兴趣&a…

Linux第9步_通过终端查看U盘文件

学习完“USB设置”后&#xff0c;我们学习通过终端来查看U盘文件。前面讲解过使用鼠标打开U盘&#xff0c;但是在实际使用中&#xff0c;更多的还是采用命令来实现对U盘的操作。 1、在桌面&#xff0c;右击鼠标&#xff0c;弹出下面的界面: 2、点击上图中的“打开终端”&#…

SCI一区级 | Matlab实现RIME-CNN-LSTM-Mutilhead-Attention多变量多步时序预测

SCI一区级 | Matlab实现RIME-CNN-LSTM-Mutilhead-Attention多变量多步时序预测 目录 SCI一区级 | Matlab实现RIME-CNN-LSTM-Mutilhead-Attention多变量多步时序预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现RIME-CNN-LSTM-Mutilhead-Attention霜冰算法…

代码随想录算法训练营第三十天|总结、332.重新安排行程、51.N皇后、37.解数独

代码随想录 (programmercarl.com) 总结 332.重新安排行程 欧拉通路和欧拉回路&#xff1a; 欧拉通路&#xff1a;对于图G来说&#xff0c;如果存在一条通路包含G的所有边&#xff0c;则该通路称为欧拉通路&#xff0c;也称欧拉路径。欧拉回路&#xff1a;如果欧拉路径是一条…

比较全面的vcruntime140_1.dll丢失的解决方法,4招搞定缺失的vcruntime140_1.dll

在平时使用电脑的过程中&#xff0c;许多人可能会碰到一个名为vcruntime140_1.dll的文件出现执行错误的问题&#xff0c;往往大家对此束手无策。针对这个问题&#xff0c;本文将向你解释vcruntime140_1.dll是什么&#xff0c;为何会发生这种无法执行代码的错误&#xff0c;以及…

互联网加竞赛 基于卷积神经网络的乳腺癌分类 深度学习 医学图像

文章目录 1 前言2 前言3 数据集3.1 良性样本3.2 病变样本 4 开发环境5 代码实现5.1 实现流程5.2 部分代码实现5.2.1 导入库5.2.2 图像加载5.2.3 标记5.2.4 分组5.2.5 构建模型训练 6 分析指标6.1 精度&#xff0c;召回率和F1度量6.2 混淆矩阵 7 结果和结论8 最后 1 前言 &…

无人地磅系统|内蒙古中兴首创无人地磅和远程高效管理的突破

走进标杆企业&#xff0c;感受名企力量&#xff0c;探寻学习优秀企业领先之道。 本期要跟砼行们推介的标杆企业是内蒙古赤峰市砼行业的龙头企业&#xff1a;赤峰中兴首创混凝土搅拌有限责任公司&#xff08;以下简称为中兴首创&#xff09;。 中兴首创成立于2011年初&#xff…

猫头虎分享已解决Bug || Go Error: cannot use str (type string) as type int in assignment

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…

AI教我学编程之C#关键字

AI教我学编程系列学习第三课 — C#关键字 前言重点先知关键字分类保留字上下文关键字 对话AI首遇波澜调整指令第一次第二次第三次直到我提出如下指令 人工智能&#xff1f;阶段总结 知识拓展1、Ecma和ISO是什么&#xff1f;2、System&#xff0c;dllhost.exe&#xff0c;taskmg…

7个Pandas绘图函数助力数据可视化

大家好&#xff0c;在使用Pandas分析数据时&#xff0c;会使用Pandas函数来过滤和转换列&#xff0c;连接多个数据帧中的数据等操作。但是&#xff0c;生成图表将数据在数据帧中可视化&#xff0c;通常比仅仅查看数字更有帮助。 Pandas具有几个绘图函数&#xff0c;可以使用它…

软件测试|Linux基础教程:ln命令与软链接和硬链接

简介 在Linux系统中&#xff0c;ln命令是一个非常有用的工具&#xff0c;用于创建链接&#xff08;link&#xff09;&#xff0c;将一个文件或目录链接到另一个位置。链接允许一个文件或目录可以同时存在于多个位置&#xff0c;而不会占用额外的磁盘空间。ln命令支持创建硬链接…

202312 青少年软件编程等级考试Scratch一级真题(电子学会)

2023年12月 青少年软件编程等级考试Scratch一级真题&#xff08;电子学会&#xff09; 试卷总分数&#xff1a;100分 试卷及格分&#xff1a;60 分 考试时长&#xff1a;60 分钟 第 1 题 单选题 观察下列每个圆形中的四个数&#xff0c;找出规律&#xff0c;在括…

用通俗易懂的方式讲解:2024 检索增强生成技术(RAG)研究进展

本篇内容1w字左右&#xff0c;稍微有点长&#xff0c;相对不容易理解&#xff0c;喜欢可以收藏、关注、点赞。 一、前言 在过去的一两年里&#xff0c;人工智能领域目睹了检索增强生成技术&#xff08;RAG&#xff09;的迅猛发展&#xff0c;这种技术结合了强大的语言模型与信…

程序员副业之AI情侣头像(手把手超详细完整全流程)

项目介绍 小黑今天给咱们分享个轻松简单的项目&#xff0c;每天不会超过半小时&#xff0c;就是用AI制作情侣头像&#xff0c;在抖音上变现。听起来是不是很科幻&#xff1f;但实际上效果杠杠的&#xff01; 最关键的是&#xff0c;收入方面&#xff0c;一单9块9&#xff0c;…

深入了解性能测试工具:优化应用性能的关键步骤

在当今数字化时代&#xff0c;应用程序性能是保持用户满意度和业务成功的关键因素之一。性能测试工具是开发和测试团队的宝贵资源&#xff0c;可以帮助识别和解决潜在的性能瓶颈&#xff0c;确保应用程序在各种负载条件下都能表现出色。本文将介绍性能测试工具的重要性、及它们…

计算机缺失vcomp120.dll文件怎么办?总结多种解决方法分享

在使用电脑过程中&#xff0c;难免会遇到各种问题&#xff0c;其中vcomp120.dll丢失问题就是其中之一。这个问题可能会给用户带来诸多不便&#xff0c;导致某些应用程序无法正常运行。在这篇文章中&#xff0c;我们将详细介绍vcomp120.dll文件的重要性&#xff0c;以及遇到丢失…

点灯大师的第一步 -imx6ull

实验目的 编写linux 的驱动程序&#xff0c;并移植到IMX6ULL -MINI开发板上&#xff0c;实现将 LED灯点亮&#xff0c;并周期性闪烁&#xff0c;周期间隔可调节的功能。出现的问题 2.1 点灯 2.1.1 设备加入到设备树中 设置pin 功能与 GPIO功能 PIN功能(PAD功能)又分为电气特性(…

TS 36.211 V12.0.0-下行(6)-同步信号

本文的内容主要涉及TS 36.211&#xff0c;版本是C00&#xff0c;也就是V12.0.0。

腾讯云服务器(免费1个月)申请流程

腾讯云免费服务器申请入口 https://curl.qcloud.com/FJhqoVDP 免费服务器可选轻量应用服务器和云服务器CVM&#xff0c;轻量配置可选2核2G3M、2核8G7M和4核8G12M&#xff0c;CVM云服务器可选2核2G3M和2核4G3M配置&#xff0c;腾讯云百科txybk.com分享2024年最新腾讯云免费服务器…