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

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

相关文章:

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

Debian或Ubuntu静态交叉编译arm和aarch64 介绍术语ARM架构前置条件从源代码编译一个简单的C程序configure和make交叉编译关于静态链接和依赖关系使用 musl libc 实现与 configure 和 make 进行交叉编译 ARM 正在获得越来越多的关注&#xff0c;并且越来越受欢迎。直接在这些基于…...

最新ai系统ChatGPT程序源码+详细搭建教程+以图生图+Dall-E2绘画+支持GPT4+Midjourney绘画

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…...

【设计模式】第16节:行为型模式之“命令模式”

一、简介 命令模式&#xff1a;将请求&#xff08;命令&#xff09;封装为一个对象&#xff0c;这样可以使用不同的请求参数化其他对象&#xff08;将不同请求依赖注入到其他对象&#xff09;&#xff0c;并且能够支持请求&#xff08;命令&#xff09;的排队执行、记录日志、…...

安装pytorch报错torch.cuda.is_available()=false的解决方法

参考文章&#xff1a; https://blog.csdn.net/qq_46126258/article/details/112708781 https://blog.csdn.net/Andy_Luke/article/details/122503884 https://blog.csdn.net/anmin8888/article/details/127910084 https://blog.csdn.net/zcs2632008/article/details/127025294 …...

自定义表格的表头根据后端的数据进行筛选是否进行自定义表头添加按钮

自定义表格的表头根据后端的数据进行筛选是否进行自定义表头添加按钮 自定义表格的表头根据后端的数据进行筛选是否进行自定义表头添加按钮 <template><div class"box"><el-table :data"msgMapList" border class"table">&l…...

海上风电应急救援vr模拟安全培训提高企业风险防范能力

相比传统的发电厂&#xff0c;海上风电作业积累的经验少&#xff0c;风险高&#xff0c;因此为了规范施工人员的行为和操作&#xff0c;保障生产安全进行&#xff0c;开展海上风电VR安全培训具有重要意义。 有助于提高员工的安全意识 通过模拟真实的海上风电作业环境&#xff0…...

自定义SpringBoot启动图标

在SpringBoot项目的resources目录下创建banner.txt文件 在https://www.bootschool.net/网站上复制Ascll艺术字&#xff08;图&#xff09;粘贴到banner.txt中保存。 启动项目就会加载 可以修改颜色&#xff0c;和版本号 ${application.version} 输出版本 ${spring-boot.v…...

diffusers-Tasks

https://huggingface.co/docs/diffusers/using-diffusers/unconditional_image_generationhttps://huggingface.co/docs/diffusers/using-diffusers/unconditional_image_generation1.Unconditional image generation 无条件图像生成是一个相对简单的任务。模型仅生成图像&…...

文件下载漏洞, 漏洞原理, 测试方法, 漏洞防御, 常见敏感路径

文件下载漏洞 一, 文件下载漏洞原理 利用条件: 1. 读取文件的路径是用户可控, 且没有校验或检验不严. 2. 使用了读取文件的函数. 3. 输出了文件内容.漏洞场景一: 后端没有限制哪些路径的文件可以下载 后端代码: http://192.168.112.200/security/download.php $file_pat…...

【零参考GAN:Pansharpening】

ZeRGAN: Zero-Reference GAN for Fusion of Multispectral and Panchromatic Images &#xff08;用于多光谱和全色图像融合的零参考GAN&#xff09; 本文提出了一种融合低空间分辨率多光谱(LR MS)和高空间分辨率全色(PAN)图像的新的全色锐化方法–零参考生成对抗网络(ZeRGAN…...

Nacos 注册中心介绍与实操

前言 本文为个人SpringCloud学习笔记&#xff0c;主要记录Nacos的注册中心实操、SpringBoot多模块编程实操等 注册中心 注册中心介绍 注册中心是微服务的一个重要组件&#xff0c;用于实现服务的注册与发现&#xff0c;主要作用包括以下&#xff1a; 服务注册&#xff1a;…...

基于51单片机的智能手机充电器设计

**单片机设计介绍&#xff0c;1660【毕设课设】基于51单片机和MAX1898的智能手机充电器设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 51单片机智能手机充电器设计介绍 51单片机智能手机充电器是一种可以实现智能快速充电的…...

nginx 和gateway配置实现动静分离和反向代理

这两个配置文件分别是Nginx和Spring Cloud Gateway的配置文件&#xff0c;它们用于构建网关服务&#xff0c;进行请求的路由和转发。 前端发送请求的时候为了不暴露服务器地址,所以会使用nginx做反向代理的一个主要作用是隐藏后端服务器的真实地址&#xff0c;从而增加网络安全…...

【深度学习实验】网络优化与正则化(二):基于自适应学习率的优化算法详解:Adagrad、Adadelta、RMSprop

文章目录 一、实验介绍二、实验环境1. 配置虚拟环境2. 库版本介绍 三、实验内容0. 导入必要的库1. 随机梯度下降SGD算法a. PyTorch中的SGD优化器b. 使用SGD优化器的前馈神经网络 2.随机梯度下降的改进方法a. 学习率调整b. 梯度估计修正 3. 梯度估计修正&#xff1a;动量法Momen…...

系统韧性研究(3)| 工程系统韧性要求

从最基本的层面上说&#xff0c;系统韧性指的是系统在逆境中继续执行其任务的程度。虽然对操作连续性至关重要&#xff0c;但系统的服务&#xff08;能力&#xff09;只是系统继续执行其任务所必须保护的一些资产。该系统必须检测不利因素&#xff0c;对其作出反应&#xff0c;…...

.net 5 发布后swagger页面不显示问题

1&#xff1a;项目右键属性-》生成xml--用于swagger文件读取 2&#xff1a;开启文件配饰swagger读取指定文件...

Spring Boot 3 整合 xxl-job 实现分布式定时任务调度,结合 Docker 容器化部署(图文指南)

目录 前言初始化数据库Docker 部署 xxl-job下载镜像创建容器并运行访问调度中心 SpringBoot 整合 xxl-jobpom.xmlapplication.ymlXxlJobConfig.java执行器注册查看 定时任务测试添加测试任务配置定时任务测试结果 结语附录xxl-job 官方文档xxl-job 源码测试项目源码 前言 xxl-…...

1985-2020年我国30m土地利用覆盖数据介绍

土地覆盖(LC)决定了地球各圈层之间的能量交换、水和碳循环。准确的 LC 信息是环境和气候研究的基本参数。考虑到在过去几十年中&#xff0c;随着经济建设的发展&#xff0c;中国发生了巨大的变化&#xff0c;连续和精细的 LC 监测是迫切需要的。然而&#xff0c;目前&#xff0…...

Django 社区志愿者管理系统

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 社区志愿者服务管理系统&#xff0c;主要的模块包括查看首页、个人中心、通知公告管理、志愿者管理、普通管理员管理、志愿活动管理、活动宣…...

wordpress如何修改数据库里用户ID下一个自增值的开始数字

有时候我们为了让别人认为网站有很多注册用户&#xff0c;会想把网站用户ID的起始数改大一点&#xff0c;因为WP默认的用户ID是从1开始&#xff0c;注册一个就加1&#xff0c;这样别人就很容易知道网站的用户量。 那么如何改呢&#xff1f;首先进phpmyadmin&#xff0c;找到wp…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...