Debian或Ubuntu静态交叉编译arm和aarch64

Debian或Ubuntu静态交叉编译arm和aarch64

  • 介绍
  • 术语
  • ARM架构
  • 前置条件
  • 从源代码编译一个简单的C程序
  • configure和make交叉编译
  • 关于静态链接和依赖关系
  • 使用 musl libc 实现与 configure 和 make 进行交叉编译

ARM 正在获得越来越多的关注,并且越来越受欢迎。直接在这些基于 ARM 的设备上构建并不总是可能的,特别是当它们的资源有限时。大多数构建和开发计算机仍然在 x86 上,通过使用交叉编译,可以构建可在其他体系结构上使用的二进制文件或可执行文件。例如,使用您的标准 PC(很可能是 x86)来构建可在其他架构(例如 ARM)上的另一台机器或设备上使用的东西。在这篇文章中,我将解释如何使用 Debian 10 或 Ubuntu 20.04 LTS 对 32 位 ARM (arm) 或 64 位 ARM (aarch64) 进行交叉编译。静态编译的好处是减少依赖,方便移植。

在这里插入图片描述

介绍

对我来说,交叉编译功能最常用于构建在基于 Linux 的设备上未安装或不可用的故障排除工具。例如,具有自定义 Linux 版本的 Raspberry Pi、NAS、路由器或接入点等设备,没有安装附加软件包的选项或安装附加软件包的选项有限。挑选一些设备随机运行一些Linux常用命令,输出如下:

/ # telnet
/bin/sh: telnet: not found
/ # tcpdump
/bin/sh: telnet: not found
/ # strace
/bin/sh: strace: not found
/ # curl
/bin/sh: curl: not found

对于下面的步骤,我将使用 Debian 10 (Buster),并且还将在 Ubuntu 20.04.1 (LTS) 上测试相同的步骤。所有步骤都经过验证可以在两者之间互换。两者的起点都是最小安装(标准系统实用程序 + SSH 服务器)。这可以确保,如果有人想要重复这些步骤,所有内容都是可重现的,并且不会跳过或遗漏任何已预安装的内容。

术语

在交叉编译中,需要使用以下令人困惑的术语:

  1. 构建平台:构建机器的架构
  2. 主机平台:您正在构建的架构
  3. 目标平台:将处理编译的二进制文件的体系结构

构建和主机或多或少是清晰的,但目标可能会令人困惑。简而言之,目标仅在使用开发工具(如编译器本身)时才相关。

在这里插入图片描述

当您为与正在使用的相同架构进行构建时,构建、主机和目标是相同的。这称为“本机”编译。如果构建和目标平台相同,但主机不同,那么我们正在讨论交叉编译,这是本文所讨论的。这三个平台都不同用于为另一种体系结构构建交叉编译器。

需要明确的是,在本文中,构建平台和目标平台是 x86_64(标准 PC),主机是 ARM 平台。我将介绍 32 位 ARM(armv6、armv7 或简称为 arm)和 64 位 ARM (aarch64)。

ARM架构

要找出需要编译哪一个(32 位或 64 位 ARM),最简单的方法是查看 uname -m 的输出。对于X86_64(标准PC),

jensd@deb10:~$ uname -m
x86_64

32位ARM,

[ap1:~]# uname -m
armv7l

64位ARM:

root@armv8:/ # uname -m
aarch64

前置条件

在开始编译之前,我们需要安装ARM交叉编译所需的软件包和工具。其中包括编译本机所需的标准工具。对于32位ARM(arm):

jensd@deb10:~$ sudo apt install gcc make gcc-arm-linux-gnueabi binutils-arm-linux-gnueabi
Reading package lists... Done
Building dependency tree
...
Processing triggers for man-db (2.8.5-2) ...
Processing triggers for libc-bin (2.28-10) ...

对于64位ARM(aarch64):

jensd@deb10:~$ sudo apt install gcc make gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu
Reading package lists... Done
...
Processing triggers for man-db (2.8.5-2) ...
Processing triggers for libc-bin (2.28-10) ...

当然,如果您计划针对这两种架构进行编译,则可以安装 32 位和 64 位所需的编译器。

从源代码编译一个简单的C程序

一旦我们安装了先决条件,我们就可以尝试编译一个简单的 C 程序。首先,我们对要进行编译的 PC 进行所谓的本机编译,以确保我们的程序能够执行我们想要的操作。将源代码保存为 helloworld.c:

#include<stdio.h>
int main()
{printf("Hello World!\n");return 0;
}

本机(x86-64)编译源代码:

jensd@deb10:~$ vi helloworld.c
jensd@deb10:~$ gcc helloworld.c -o helloworld-x86_64

要查看编​​译结果的类型和平台,我们可以使用file工具检查输出:

jensd@deb10:~$ file helloworld.x86_64
helloworld.x86_64: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=f55972265cd343c3110a5d339d71caeed755c23e, not stripped

我们可以执行二进制文件来检查结果:

jensd@deb10:~$ ./helloworld-x86_64
Hello World!
jensd@deb10:~$

下一步是为 ARM 编译相同的源代码。我们只需使用不同的编译器(对于 32 位 ARM,使用 arm-linux-gnueabi-gcc 代替 gcc;对于 64 位 ARM 或 aarch64,使用 gcc-aarch64-linux-gnu)来完成此操作。32位ARM编译:

jensd@deb10:~$ arm-linux-gnueabi-gcc helloworld.c -o helloworld-arm -static
jensd@deb10:~$ file helloworld-arm
helloworld-arm: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=971f8b03dcb473de2caa1abbb63990977c6478b3, not stripped

64位ARM编译:

jensd@deb10:~$ aarch64-linux-gnu-gcc helloworld.c -o helloworld-aarch64 -static
jensd@deb10:~$ file helloworld-aarch64
helloworld-aarch64: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.7.0, BuildID[sha1]=428239fafd78d5fd28dc400e913618817224ea50, not stripped

file命令行输出给了我们一个不同的结果,这是我们所期望的。正如预期的那样,尝试在构建机器 (x86_64) 上执行这些二进制文件将导致错误:

jensd@deb10:~$ ./helloworld-aarch64
-bash: ./helloworld-aarch64: cannot execute binary file: Exec format error
jensd@deb10:~$ ./helloworld-arm
-bash: ./helloworld-arm: cannot execute binary file: Exec format error

为了测试这是否有效,我们需要一台运行我们构建的架构的机器或设备:

root@armv8:/$ uname -a
Linux armv8 4.4.214-armada-17.10.1 #1 SMP Fri Jul 31 23:23:54 UTC 2020 aarch64 aarch64 aarch64 GNU/Linux
root@armv8:/$ uname -m
aarch64
root@armv8:/$ wget http://192.168.1.1/helloworld-aarch64
...
helloworld-aarch64 100% |******************************| 557k 0:00:00 ETA
...
root@armv8:/ # chmod +x helloworld-aarch64
root@armv8:/ # ./helloworld-aarch64
Hello World!

上面的输出显示,我们的小程序在交叉编译后在 ARM 上运行得很好!

configure和make交叉编译

上面的例子非常简单,但是当从较大的项目编译源代码时,通常是通过使用configure生成一个makefile,然后使用make运行编译和其他必要的步骤来完成的。要将 gcc 替换为另一个特定于目标平台的编译器将需要大量工作。幸运的是,大多数时候您可以在运行配置时指定要编译的平台。

作为示例,我将为 strace 的 ARM aarch64 创建一个二进制文件。为了避免出现与嵌入式 ARM 设备的依赖关系问题,我将提供静态选项(有关更多说明,请参阅下文)。

第一步是从 https://github.com/strace/strace/releases/tag/v5.10 获取 strace 的源代码并提取它:

jensd@deb10:~$ wget https://github.com/strace/strace/releases/download/v5.10/strace-5.10.tar.xz
...
strace-5.10.tar.xz    100%[===============>]   1.77M  2.49MB/s    in 0.7s
2021-01-26 16:57:20 (2.49 MB/s) - ‘strace-5.10.tar.xz’ saved [1859688/1859688]
jensd@deb10:~$ tar -xf strace-5.10.tar.xz
jensd@deb10:~$ cd strace-5.10/
jensd@deb10:~/strace-5.10$

下一步是运行配置。但这里我们需要指定构建和主机平台,以便我们最终得到 ARM 的二进制文件(静态链接):

jensd@deb10:~/strace-5.10$ ./configure --build x86_64-pc-linux-gnu --host aarch64-linux-gnu LDFLAGS="-static -pthread" --enable-mpers=check
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane… yes
checking for aarch64-linux-gnu-strip... aarch64-linux-gnu-strip
...
config.status: creating strace.spec
config.status: creating debian/changelog
config.status: creating config.h
config.status: executing depfiles commands
jensd@deb10:~/strace-5.10$

此时,我们已准备好通过运行 make 来进行实际的交叉编译:

jensd@deb10:~/strace-5.10$ make
aarch64-linux-gnu-gcc -E -P -DHAVE_CONFIG_H   \
...
jensd@deb10:~/strace-5.10$ file strace
strace: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.7.0, BuildID[sha1]=db1ce4305df1dac73b81efe99847725d65ac9ab4, with debug_info, not stripped

正如您所看到的,我构建了这个用于 aarch64 的版本。如果您想对armv6或armv7执行相同的操作,只需在运行configure时将–host aarch64-linux-gnu替换为–host arm-linux-gnueabi即可。

为了使其正常工作,我传递给 ./configure 的标志和参数有一些额外的解释:

checking for library containing timer_create… no
configure: error: failed to find timer_create
was fixed by adding LDFLAGS=”-pthread”
checking for m32 personality compile support… no
checking whether to enable m32 personality support… no
configure: error: Cannot enable m32 personality support
was fixed by adding –enable-mpers=check

与小型 C 程序一样,是时候在 ARM 上测试编译后的二进制文件了:

root@armv8:/data $ uname -a
Linux armv8 4.4.214-armada-17.10.1 #1 SMP Fri Jul 31 23:23:54 UTC 2020 aarch64 aarch64 aarch64 GNU/Linux
root@armv8:/data $ uname -m
aarch64
root@armv8:/data $ wget http://192.168.1.1/strace 
...
strace               100%  |************************| 5989k  0:00:00 ETA
...
root@armv8:/data $ chmod +x strace
root@armv8:/data $ ./strace -V
strace -- version 5.10
Copyright (c) 1991-2020 The strace developers https://strace.io.
This is free software; see the source for copying conditions.  There is NOwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.Optional features enabled: no-m32-mpers

这使我们能够在随机的 aarch64 机器上简单地复制和使用 strace。

关于静态链接和依赖关系

正如我在一开始提到的,我主要使用交叉编译来构建故障排除工具。通常,您构建的平台是有限的。这可能是由于缺乏资源(例如嵌入式设备)造成的。但也因为预构建的软件包要么不可用,要么无法安装。在很多情况下,这也意味着为您正在构建的任何内容安装依赖项可能会出现问题。显然,这些依赖关系也必须针对同一架构构建。

如果您有这种限制,或者您只是希望二进制文件在该架构上运行。无需担心依赖项或可能已安装的这些依赖项的冲突(旧)版本,您可以使用静态链接。这意味着在构建时所有必需的依赖项都将包含在二进制文件本身中。

静态链接有一些缺点,因为它可能不安全(所包含的依赖项不会随系统更新),当执行较低级别系统调用的库和生成的二进制文件较大时,可能会导致不兼容。在构建故障排除工具时,我可以忍受这些事情,因为它们不适合长期使用。

在这里插入图片描述

虽然静态链接可能是您正在寻找的,但它并不总是那么容易实现。尤其是与交叉编译相结合,它会让你头疼。大多数工具都依赖于 libc 或 glibc,出于我在上一段中提到的充分理由,这不鼓励静态链接。幸运的是,有一个从头开始开发的 libc 实现,它允许对 libc 依赖项进行正确的静态链接:musl(发音为 musscle)。

使用 musl libc 实现与 configure 和 make 进行交叉编译

为了使用 musl,我们需要下载正确的版本进行交叉编译。您可以在这里找到完整列表:https://musl.cc/#binaries。

下载后,我们可以提取存档并测试这是否适用于我们的构建机器:

jensd@deb10:~$ wget https://musl.cc/aarch64-linux-musl-cross.tgz
...
aarch64-linux-musl-cross.tgz   100%[============>]   103.69M  6.81MB/s    in 16s
2021-01-27 15:19:55 (6.42 MB/s) - ‘aarch64-linux-musl-cross.tgz’ saved [108731156/108731156]
jensd@deb10:~$ tar -xvzf aarch64-linux-musl-cross.tgz
aarch64-linux-musl-cross/
aarch64-linux-musl-cross/usr
...
jensd@deb10:~$ ./aarch64-linux-musl-cross/bin/aarch64-linux-musl-gcc --version
aarch64-linux-musl-gcc (GCC) 10.2.1 20210116
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

接下来,我将为 aarch64 构建 TCPdump 的静态链接版本。当您需要记录、调查或排除网络连接故障时,它始终是一个方便使用的好工具。不幸的是,tcpdump 并不总是可用,或者在最好的情况下作为有限的 Busybox 版本。首先,我们需要安装一些必需的工具,这些工具由 tcpdump 用于构建过程:

jensd@deb10:~$ sudo apt install flex bison
Reading package lists... Done
Building dependency tree
...
Processing triggers for man-db (2.8.5-2) ...
Processing triggers for libc-bin (2.28-10) ...

接下来,我们需要下载 tcpdump 和 libpcap 的源代码并解压。您可以在这里找到最新版本:https://www.tcpdump.org/index.html#latest-releases

jensd@deb10:~$ wget https://www.tcpdump.org/release/libpcap-1.10.0.tar.gz
...
libpcap-1.10.0.tar.gz   100%[============>]   912.66K  1.51MB/s    in 0.6s
2021-01-27 15:20:22 (1.51 MB/s) - ‘libpcap-1.10.0.tar.gz’ saved [934559/934559]
jensd@deb10:~$ tar -xvzf libpcap-1.10.0.tar.gz
jensd@deb10:~$ wget https://www.tcpdump.org/release/tcpdump-4.99.0.tar.gz
...
tcpdump-4.99.0.tar.gz   100%[============>]   1.92M  2.57MB/s    in 0.7s
2021-01-27 15:21:36 (2.57 MB/s) - ‘tcpdump-4.99.0.tar.gz’ saved [2008080/2008080]
jensd@deb10:~$ tar -xvzf tcpdump-4.99.0.tar.gz

下载并解压源代码后,我们需要首先运行 libpcap 的配置脚本。只是这一次,我们需要将编译器设置为 musl-compiler 以进行交叉编译,方法是将 CC 设置为:aarch64-linux-musl-gcc:

jensd@deb10:~$ cd libpcap-1.10.0/
jensd@deb10:~/libpcap-1.10.0$ CC=/home/jensd/aarch64-linux-musl-cross/bin/aarch64-linux-musl-gcc ./configure --build x86_64-pc-linux-gnu --host aarch64-linux-gnu LDFLAGS="-static"
checking build system type... x86_64-pc-linux-gnu
checking host system type... aarch64-unknown-linux-gnu
...
config.status: creating config.h
config.status: executing default-1 commands

如果一切顺利,我们可以通过发出 make 来实际编译 libpcap:

jensd@deb10:~/libpcap-1.10.0$ make
...
config.status: creating pcap-config.tmp
mv pcap-config.tmp pcap-config
chmod a+x pcap-config

现在,我们可以对 tcpdump 本身重复相同的操作(./configure 和 make)。通过进行静态链接,将包含 libpcap,结果是单个二进制 tcpdump:

jensd@deb10:~/libpcap-1.10.0$ cd ../tcpdump-4.99.0/
jensd@deb10:~/tcpdump-4.99.0$ CC=/home/jensd/aarch64-linux-musl-cross/bin/aarch64-linux-musl-gcc ./configure --build x86_64-pc-linux-gnu --host aarch64-linux-gnu LDFLAGS="-static"
checking build system type... x86_64-pc-linux-gnu
checking host system type... aarch64-unknown-linux-gnu
checking for aarch64-linux-gnu-gcc... /home/jensd/aarch64-linux-musl-cross/bin/aarch64-linux-musl-gcc
checking whether the C compiler works... yes
...
config.status: creating Makefile
config.status: creating tcpdump.1
config.status: creating config.h
config.status: executing default-1 commands
jensd@deb10:~/tcpdump-4.99.0$ make
...
aarch64-linux-gnu-ranlib libnetdissect.a/home/jensd/aarch64-linux-musl-cross/bin/aarch64-linux-musl-gcc  -DHAVE_CONFIG_H   -I. -I../libpcap-1.10.0  -I/usr/inet6/include -g -O2 -static -o tcpdump fptype.o tcpdump.o  libnetdissect.a ../libpcap-1.10.0/libpcap.a
jensd@deb10:~/tcpdump-4.99.0$ file tcpdump
tcpdump: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, with debug_info, not stripped

正如您在最后一个命令中看到的,我们有静态链接的 tcpdump 二进制文件。如果一切顺利,我们应该能够在基于 aarch64 的机器上执行此操作,而无需任何进一步的依赖。

root@armv8:/$ uname -m
aarch64
root@armv8:/$ wget http://192.168.1.1/tcpdump
...
tcpdump   100%[============>]   6.73M  --.-KB/s    in 0.1s
2021-01-27 13:55:49 (52.5 MB/s) - 'tcpdump' saved [7061368/7061368]
root@armv8:/$ chmod +x tcpdump
root@armv8:/$ ./tcpdump -i eth0
tcpdump: verbose output suppressed, use -v[v]for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
13:57:20.452643 IP 192.168.0.90.34020 > 192.168.1.10.9000: Flags [S], seq 3386726277, win 64240, options [mss 1460,sackOK,TS val 3092573417 ecr 0,nop,wscale 7], length 0
13:57:20.452715 IP 192.168.1.10.9000 > 192.168.0.90.34020: Flags [S.], seq 3761157769, ack 3386726278, win 28960, options [mss 1460,sackOK,TS val 4397992 ecr 3092573417,nop,wscale 7], length 0
13:57:20.453325 IP 192.168.0.90.34020 > 192.168.1.10.9000: Flags [.], ack 1, win 502, options [nop,nop,TS val 3092573418 ecr 4397992], length 0
13:57:20.508762 IP 192.168.1.10.46819 > 8.8.8.8.53: 15310+ PTR? 90.0.168.192.in-addr.arpa. (43)^C
4 packets captured
23 packets received by filter
5 packets dropped by kernel
root@armv8:/$

正如您所看到的,tcpdump 工作正常并且不需要任何依赖项。如果您需要在工具集非常有限并且无法轻松安装它们的平台上工作或排除故障,这确实很有帮助。您只需复制该文件即可运行。

作者:岬淢箫声
日期:2023年10月31日
版本:1.0
链接:http://caowei.blog.csdn.net

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

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

相关文章

深度学习_3 数据操作之线代,微分

线代基础 标量 只有一个元素的张量。可以通过 x torch.tensor(3.0) 方式创建。 向量 由多个标量组成的列表&#xff08;一维张量&#xff09;。比如 x torch.arange(4) 就是创建了一个1*4的向量。可以通过下标获取特定元素&#xff08;x[3]&#xff09;&#xff0c;可以通…

Web3时代:探索DAO的未来之路

Web3 的兴起不仅代表着技术进步&#xff0c;更是对人类协作、创新和价值塑造方式的一次重大思考。在 Web3 时代&#xff0c;社区不再仅仅是共同兴趣的聚集点&#xff0c;而变成了一个价值交流和创新的平台。 去中心化&#xff1a;超越技术的革命 去中心化不仅仅是 Web3 的技术…

Linux进程概念(1)

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;Linux &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要内容为进程的概念做铺垫&#xff0c;主要介绍冯诺依曼体系结…

Pycharm安装jupyter和d2l

安装 jupyter: jupyter是d2l的依赖库&#xff0c;没有它就用不了d2l pycharm中端输入pip install jupyter安装若失败则&#xff1a; 若网速过慢&#xff0c;则更改镜像源再下载&#xff1a; pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ pip …

【ElasticSearch系列-03】ElasticSearch的高级句法查询Query DSL

ElasticSearch系列整体栏目 内容链接地址【一】ElasticSearch下载和安装https://zhenghuisheng.blog.csdn.net/article/details/129260827【二】ElasticSearch概念和基本操作https://blog.csdn.net/zhenghuishengq/article/details/134121631【二】ElasticSearch的高级查询Quer…

Mac之NVM|通过brew安装、更新、卸载、重新安装nvm

文章目录 导文通过brew安装NVM通过brew更新NVM通过brew卸载NVM通过brew重新安装NVM 导文 Mac之NVM 通过brew安装、更新、卸载、重新安装 通过brew安装NVM brew install nvm通过brew更新NVM brew upgrade nvm通过brew卸载NVM brew uninstall nvm通过brew重新安装NVM brew re…

快手协议算法最新版

快手的协议分析是指对快手算法系统进行分析&#xff0c;以了解其推荐内容和个性化用户体验的机制。 然而&#xff0c;一般来说&#xff0c;协议分析的目标是理解算法系统中各个组成部分的功能和作用&#xff0c;以及它们之间的相互关系。以下是一些常见的分析方向&#xff1a;…

Python 自动化(十六)静态文件处理

准备工作 将不同day下的代码分目录管理&#xff0c;方便后续复习查阅 (testenv) [rootlocalhost projects]# ls day01 day02 (testenv) [rootlocalhost projects]# mkdir day03 (testenv) [rootlocalhost projects]# cd day03 (testenv) [rootlocalhost day03]# django-admi…

springboot--多环境配置快速切换开发、测试、生产环境

多环境配置快速切换开发、测试、生产环境 前言1、使用1.1指定环境Profile({"dev","test"})Spring Profiles 提供一个隔离配置的方式&#xff0c;使其仅在特定环境生效 任何Component,Configuration或ConfigurationProperties 可以使用Profile标记&#xff…

损失函数总结(十四):RMSELoss、LogCosh Loss

损失函数总结&#xff08;十四&#xff09;&#xff1a;RMSELoss、LogCosh Loss 1 引言2 损失函数2.1 RMSELoss2.2 LogCosh Loss 3 总结 1 引言 在前面的文章中已经介绍了介绍了一系列损失函数 (L1Loss、MSELoss、BCELoss、CrossEntropyLoss、NLLLoss、CTCLoss、PoissonNLLLos…

【2021集创赛】Risc-v杯一等奖:自适应噪声环境的超低功耗语音关键词识别系统

本作品参与极术社区组织的有奖征集|秀出你的集创赛作品风采,免费电子产品等你拿~活动。 团队介绍 参赛单位&#xff1a;东南大学 队伍名称&#xff1a;Hey Siri 指导老师&#xff1a;刘波 参赛队员&#xff1a;钱俊逸、张人元、王梓羽 总决赛奖项&#xff1a;全国一等奖 摘要…

Redis高可用(主从复制,哨兵,集群)

Redis主从复制 主从复制&#xff0c;是指将一台Redis服务器的数据&#xff0c;复制到其他的Redis服务器。前者称为主节点&#xff08;Master&#xff09;&#xff0c;后者称为从节点&#xff08;slave&#xff09;&#xff1b;数据的复制是单向的&#xff0c;只能由主节点到从…

OpenGL ES相关库加载3D 车辆模型

需求类似奇瑞的这个效果&#xff0c;就是能全方位旋转拖拽看车&#xff0c;以及点击开关车门车窗后备箱等 瑞虎9全景看车 (chery.cn) 最开始收到这个需求的时候还有点无所适从&#xff0c;因为以前没有做过类似的效果&#xff0c;后面一经搜索后发现实现的方式五花八门&#xf…

sqli 靶场 Level23-Level30 wp

level-23 &#xff08;注释被过滤&#xff09; 抓包&#xff0c;查看正常请求和响应。 略 尝试是否存在注入 id1’,id1’&#xff0c;成周期性变化 尝试 POC POC: id1andextractValue(1,concat(0x7e,user()))-- 结果&#xff1a;failed。怀疑–被过滤掉了&#xff0c;尝试…

深度学习实战:基于TensorFlow与OpenCV的手语识别系统

文章目录 写在前面基于TensorFlow与OpenCV的手语识别系统安装环境一、导入工具库二、导入数据集三、数据预处理四、训练模型基于CNN基于LeNet5基于ResNet50 五、模型预测基于OpenCV 写在后面 写在前面 本期内容&#xff1a;基于TensorFlow与OpenCV的手语识别系统 实验环境&…

PFMEA详解结构分析——Sun FMEA软件

FMEA从1949年诞生到今天已经发生过多次更新&#xff0c;最新版本是2019年6月发布的《AIAG VDA FMEA手册》。新手册借鉴了AIAG的方框图、参数图、流程图等工具的运用&#xff0c;也借鉴了VDA的五步过程导向法&#xff0c;并在此基础上头尾各增加一步&#xff0c;形成了FMEA七步法…

云原生安全日志审计

记得添加&#xff0c;把配置文件挂载进去 - mountPath: /etc/kubernetes/auditname: audit-policyreadOnly: true.....- hostPath:path: /etc/kubernetes/audit/type: DirectoryOrCreatename: audit-policy/etc/kubernetes/manifests/kube-apiserver.yaml 具体配置文件如下 a…

阿里云2023年双11大促活动优惠券领取与使用及特惠云服务器产品购买规则汇总

2023年阿里云双11大促活动正在火热进行中&#xff0c;今年的双11活动还是延续了去年金秋云创季的活动名称&#xff0c;对于大部分用户来说&#xff0c;最为关心的是活动优惠券与云服务器的优惠政策&#xff0c;在我们领取双11优惠券和购买双11活动云服务器的时候&#xff0c;应…

京东大数据平台(京东数据分析):9月京东牛奶乳品排行榜

鲸参谋监测的京东平台9月份牛奶乳品市场销售数据已出炉&#xff01; 9月份&#xff0c;牛奶乳品市场销售呈大幅上涨。鲸参谋数据显示&#xff0c;今年9月&#xff0c;京东平台牛奶乳品市场的销量为2000万&#xff0c;环比增长约65%&#xff0c;同比增长约3%&#xff1b;销售额为…

HT3163 免电感滤波 音频功率放大器工作原理

HT3163是一款G效AB/D类音频功率放大器。在D类模式&#xff0c;18V供电、THDN10%条件下&#xff0c;能够持续提供40W/4Ω功率输出。在AB类模式&#xff0c;12V供电、THDN10%条件下&#xff0c;能够持续输出17W/4Ω功率。 HT3163具有防削顶失真&#xff08;ACF&#xff09;输出控…