OpenHarmony下musl编译工具链普法

OpenHarmony下musl编译工具链普法



引言

欠的债总是要还的,这不前面欠的关于OpenHarmony下musl相关的还是要还的。这里我对其中的相关知识点,梳理,归纳重新消化下!



一.GCC/Clang/LLVM的区别与联系

说实话,这块我现在都木有搞清楚,GCC/Clang/LLVM之间的区别与联系!这里只能硬着头皮,捡一捡网上各路大神的总结,先理解一波有个基本概念!

先了解,后面再深入吗!先搞个普法,对概念先有个基本的认识!


1.1 GCC的简介

传统的编译器譬如gcc设计是分为三个部分,如下图所示:

  • 前端, front end:解析源码,检查错误(词法分析(lexical analysis), 语法分析(syntax analysis), 语义分析(semantic analysis)),所以前端又称为分析阶段。并且构建一个特定于语言的抽象语法树(Abstract Syntax Tree,AST)来代表输入的代码。

  • 优化器,optimizer :负责进行各种转换尝试,改善代码的执行时间,比如消除冗余计算。通常或多或少与语言及目标无关。

  • 后端,back end:代码产生器,将代码映射到目标指令集,除了编写正确的代码外,它还负责生成利用所支持体系结构的不寻常特性的良好代码。一个编译器后端的通用部分包含指令选择,寄存器分配,及指令调度(instruction selection, register allocation, and instruction scheduling)

image


1.2 GCC架构的优点

GCC架构的优点总结为如下几点:

  • 使用通用的中间代码,新增支持语言只需要新增一个前端,新增支持目标机器只需要新增一个后端
  • 针对前后端,开发人员技术栈不同,开发人员只需要关注自身的技术栈,有利于让更多人员参与进来

总结来说,前端+优化器+后端的结构有三大好处:灵活程度高,组件复用率高,维护成本低


1.3 GCC架构的缺点

  • GCC的三段式模块必须配套使用,很难做到部分重用
  • 不能将 GCC 部分功能作为库重用的原因有很多,包括滥用全局变量、不可变变量不能更改限制不严、设计不良的数据结构、庞大的代码库、以及使用宏来防止代码库一次编译可以支持多个编译前端-目标机对。不过,最难解决的问题是其早期设计和那个时代所固有的架构设计。具体来说,GCC 饱受分层问题和抽象漏洞的困扰:编译后端遍历编译前端抽象语法树(AST)来生成调试信息(debug info),编译前端生成编译后端数据的结构,整个编译器依赖命令行设置的全局数据结构。

上面的这些优缺点,不是专业人士基本是体会不到相关差异的。我是木有体会到!


1.4 LLVM介绍

LLVM是开源的编译器(compiler)架构,以cpp编写而成,用于优化以随意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、执行时间(run-time)以及空暇时间(idle-time),对开发人员保持开放,并兼容已有脚本。LLVM的设计就采用了上述前端+优化器+后端的设计。如下图所示:

image

基于这个认知,我们可以认为 LLVM 包括了两个概念:一个广义的 LLVM 和一个狭义的 LLVM 。广义的 LLVM 指的是一个完整的 LLVM 编译器框架系统,包括了前端、优化器、后端、众多的库函数以及很多的模块;而狭义的 LLVM 则是聚焦于编译器后端功能的一系列模块和库,包括代码优化、代码生成、JIT 等。

整体的编译器架构就是 LLVM 架构:

  • Clang 大致可以对应到编译器的前端,主要处理一些和具体机器无关的针对语言的分析操作;
  • 编译器的优化器和后端部分就是之前提到的 LLVM 后端,即狭义的 LLVM。

此外,由于 LLVM 的命名最早源自于底层虚拟机(Low Level Virtual Machine) 的首字母缩写,但这个项目的范围并不局限于创建一个虚拟机,这个缩写导致了大量的疑惑。LLVM 成长之后已成为众多编译工具及低级工具技术的统称,使得这个名字变得更不贴切,所以开发者决定放弃这个缩写的涵义,现在 LLVM 已独立成为一个品牌,适用于 LLVM 下的所有项目,包括 LLVM 中介码、LLVM 除错工具、LLVM cpp 标准库等。

image


1.5 clang介绍

Clang 是一个 C、cpp、Objective-C 和Objective-cpp编程语言的编译器前端,采用底层虚拟机(LLVM)作为后端。

  • Clang 采用的是 BSD 协议的许可证,而 GCC 采用的是 GPL 协议,显然前者更为宽松;
  • Clang 是一个高度模块化开发的轻量级编译器,编译速度快、占用内存小、有着友好的出错提示
  • Clang项目包括Clang前端和Clang静态分析器等,目的是输出代码对应的抽象语法树并将代码编译成LLVM bitcode
  • 接着后端使用LLVM编译成平台相关的机器语言

1.6 gcc和clang的交叉编译

gcc和clang都支持交叉编译链,gcc这个就比较常见了像后面章节2.2所描述的就是gcc的一个交叉编译工具链!clang通过–target=基本选项是定义目标体系结构,triple 的一般格式为<sub>---,其中:

  • arch = x86_64、i386、arm、thumb、mips等。
  • sub = v5, v6m, v7a, v7m等。
  • vendor = pc, apple, nvidia, ibm,等。
  • sys = none, linux, win32, darwin, cuda等。
  • abi = eabi, gnu, android, macho, elf等。

譬如:

--target=arm-linux-gnueabihf

并且通常一个大型的编译工程,不会是上面这么直接裸写的,一般会通过环境变量进行控制的。

export LINUX_ROOT="$HOME/OH_V3.2_BETA2/code-v3.2-Beta2"
export SYSROOT="${LINUX_ROOT}/OpenHarmony/out/rk3568/obj/third_party/musl"
export LLVM_BUILD_DIR="${LINUX_ROOT}/llvm"
export PATH=${LINUX_ROOT}/OpenHarmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin:$PATH
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-ohos-
export HOSTCC=clang
export BUILD=debug

1.使用Clang作为编译器 —— 使用 Clang 交叉编译
2. 使用 Clang 交叉编译
3. How To Cross-Compile Clang/LLVM using Clang/LLVM
4. LLVM cross-compiled Linux From Scratch: C & cpp libraries


1.7 小结

前面说了这么多,其实我也还还不是很清楚!先不管吗,先把参考的链接放上!

这里我对gcc,clang和llvm的理解可以用一句话来概括就是: gcc = clang(前端) + 狭义的llvm后端

1.经典编译器组成(前端+优化器+后端)以及LLVM和Clang简介
2.【编译原理】GCC/Clang/LLVM的区别与联系
3.请问LLVM与GCC之间的关系
4.GCC和clang/LLVM
5.详解三大编译器:gcc、llvm 和 clang




二.musl你究竟是个啥

musl你是个啥,还得从它的的出生,发展历程出发一一道来。这里我们就从各个方面来捋一捋它!musl 是基于 Linux 系统调用 API 之上实现的 C 语言标准库(libc),历史可以追溯到 2005 年,但在 2011 年才正式确定了 MUSL 这个名称,开始对标 glibc、uClibc,从 2012 年开始,musl 开始使用 MIT License。

musl 致力于简单、高效,凭借 libc 优秀的松耦合性,做到了静态版本最小10kB,即使添加了线程等高级特性,也可以控制到 50kB,所以特别适合嵌入式设备。为了控制资源的使用, musl自己竟然不做动态内存分配。


2.1 glibc和musl-libc

这个我们分别来介绍下:

  • glibc: glibc是GNU C Library 是GNU项目(GNU Project),所实现的 C语言标准库(C standard library)。 目前,常见的桌面和服务器中的GNU/Linux类的系统中,都是用的这套C语言标准库。 其实现了常见的C库的函数,支持很多种系统平台,功能很全,但是也相对比较臃肿和庞大

  • musl-libc:C语言标准库Musl-libc项目发布了1.0版。Musl是一个轻量级的C标准库,设计作为GNU C library (glibc)、 uClibc或Android Bionic的替代用于嵌入式操作系统和移动设备。它遵循POSIX 2008规格和 C99 标准,采用MIT许可证授权,使用Musl的Linux发行版和项目包括sabotage,bootstrap-linux,LightCube OS等等

musl libc 和 glibc 是两个常见的 C 标准库实现,它们有一些差异。下面列出了其中一些主要的差异:

  • 大小和速度:musl libc 要小得多,因为它没有像 glibc 那样提供大量的额外功能。相反,musl libc 专注于尽可能减少代码大小和函数调用开销,以提高性能。

  • 兼容性:glibc 是 Linux 系统上最常见的 C 标准库,并且具有广泛的兼容性,支持许多架构和操作系统。相比之下,musl libc 对其他平台和操作系统的移植性较差。

  • 实现方法:musl libc 是使用静态链接编译的,这使得它更易于构建和管理,并且不需要动态链接器。相反,glibc 使用动态链接器,这也使得它更灵活,因为它可以动态加载所需的库。

  • POSIX 标准:musl libc 更加严格地遵循 POSIX 标准,而glibc 则添加了一些扩展,以提供更多的功能和兼容性。

  • 错误处理:musl libc 实现的错误处理更严格和更规范,而 glibc 则有更多的错误处理选项,并且支持不同的语言环境。

  • 版权问题:由于采用了 BSD 许可证,musl libc 比 glibc 更容易以开源、商业和专有软件的形式使用。

综上所述,选择使用 musl libc 还是 glibc 取决于您的具体需求。如果您需要一个小巧且速度较快的 C 标准库,在 Linux 系统上使用,则可以考虑使用 musl libc。如果您需要更广泛的兼容性和功能,则可以使用 glibc。

  • 额外补充:两个都是C++标准库。libc++是针对clang编译器特别重写的cpp标准库,那libstdc++自然就是gcc的事儿了。

  • 无关的科普: libc.so.6是c运行时库glibc的软链接,而系统几乎所有程序都依赖C运行时库。程序启动和运行时,是根据libc.so.6软链接找到glibc库。删除libc.so.6将导致系统的几乎所有程序不能工作。如果程序编译的时候链接的libc库版本不在程序运行环境下的glibc库支持的libc版本之内,也会报错。于是,系统的所有命令 IS,cp,cd等等都无法使用了。

1.Musl libc:为什么我们会需要另一个 libc?
2.musl和glibc,性能区别到底有多大
3.理清gcc、glibc、libstdc++的关系
4.uclibc、eglibc、glibc、Musl-libc之间的区别和联系
5.如何紧急修复,当你在linux中干穿了libc丢了libc.so.6,ld-linux-x86-64.so.2其中一个

干穿了,我就提桶跑路,还修复个啥!

6.musl简介
7.glibc和musl libc的区别
8.在同一个进程中加载​​ musl libc.so 和 gcc libc.so?
9.musl 的 GCC 包装器与 musl 的交叉编译器有何不同?
10.gcc编译静态库到自己的程序 解决在不同linux下因libc版本问题而不能运行 版本兼容问题
11.glib和glibc的联系区别
12.libc、glibc 和 glib 的关系
13.glibc所包含的各个库


2.2 aarch64-linux-musl-xxx

前面搞完了一个musl-libc库,这里又来了一个aarch64-linux-musl-xxx。你们是逗比吗,来这么多。真的逗比,今天又联系补上!

这里我们对aarch64-linux-musl其简单介绍下:

  • aarch64 是随 ARMv8 ISA 一起引入的 64 位架构,用于执行 A64 指令的计算机。而且在 aarch64 状态下执行的代码只能使用 A64 指令集。,而不能执行 A32 或 T32 指令。但是,与 AArch32 中不同,在64位状态下,指令可以访问 64 位和 32 位寄存器。

  • aarch64-linux-musl 是一个交叉编译工具链,可以在其他架构的系统中,编译安装 64 位 arm 架构的程序。常用在嵌入式代码的移植中。aarch64-linux-musl 是由musl官网基于 GCC 推出的的 ARM 交叉编译工具。可用于交叉编译 ARMv8 64 位目标中的裸机程序、u-boot、Linux kernel、filesystem 和 App 应用程序。aarch64-linux-musl 交叉编译器必须安装在 64 位主机上,才能编译目标代码。

aarch64-linux-musl-xxx如下所示:

$/opt/musl/bin$ ls
aarch64-linux-musl-addr2line  aarch64-linux-musl-gcc-9.4.0   aarch64-linux-musl-nm
aarch64-linux-musl-ar         aarch64-linux-musl-gcc-ar      aarch64-linux-musl-objcopy
aarch64-linux-musl-as         aarch64-linux-musl-gcc-nm      aarch64-linux-musl-objdump
aarch64-linux-musl-c++        aarch64-linux-musl-gcc-ranlib  aarch64-linux-musl-ranlib
aarch64-linux-musl-cc         aarch64-linux-musl-gcov        aarch64-linux-musl-readelf
aarch64-linux-musl-c++filt    aarch64-linux-musl-gcov-dump   aarch64-linux-musl-size
aarch64-linux-musl-cpp        aarch64-linux-musl-gcov-tool   aarch64-linux-musl-strings
aarch64-linux-musl-elfedit    aarch64-linux-musl-gprof       aarch64-linux-musl-strip
aarch64-linux-musl-g++        aarch64-linux-musl-ld
aarch64-linux-musl-gcc        aarch64-linux-musl-ld.bfd

这里我们可以把 aarch64-linux-musl-xxx和aarch64-linux-gnu-gcc做对比。它是一个gcc交叉编译工具链。

XXX:/opt/musl$ tree -L 1
.
├── aarch64-linux-musl
├── bin
├── include
├── lib
├── libexec
└── share#其中git仓库地址如下,对应的https://github.com/richfelker/musl-cross-make.git
https://gitee.com/stesen/musl-cross-make_for_openharmony.git


三.其它关于工具链知识的一些普法

工具链的知识真多,搞了一个又是一个!搞不完,记不住。但是还是木的办法,只能硬着头皮上!我不入地狱谁入地狱。我是超人!


3.1 什么是sysroot

sysroot 被称为逻辑根目录,只在链接过程中起作用,作为交叉编译工具链搜索库文件的根路径,如配置–sysroot=dir,则dir作为逻辑根目录,链接器将在dir/usr/lib中搜索库文件。

export LINUX_ROOT="$HOME/xxx/linux"
export SYSROOT="${LINUX_ROOT}/sysroot-ubuntu-20.04-arm64"export LINUX_ROOT="$HOME/OH_V3.2_BETA2/code-v3.2-Beta2"
export SYSROOT="${LINUX_ROOT}/OpenHarmony/out/rk3568/obj/third_party/musl"

只有链接器开启了–with-sysroot选项,–sysroot=director才生效

1.编译链接实战(4)–sysroot和-isysroot选项对编译的影响
2.GCC编译选项和环境变量
3.sysroot位何物


3.2 pkg-config是个什么东东?

pkg-config的功能主要是在编译应用程序和库的时候作为一个工具来使用。pkg-config可以使用第三方库编译程序,指定库文件和头文件的位置。pkg-config就是通过.pc文件获取库的各种必要信息,包括版本信息、编译和链接需要的参数等。不同的系统的库文件的路径不同,用户也可以把库安装到不同的目录下

对于一个比较大第三方库,其头文件和库文件的数量是比较多的。如果我们一个个手动地写,那将是相当麻烦的。所以,pkg-config就应运而生了。大家应该都知道一般用第三方库的时候,就少不了要使用到第三方的头文件和库文件。我们在编译、链接的时候,必须要指定这些头文件和库文件的位置。对于一个比较大的第三方库,其头文件和库文件的数量是比较多的,如果我们一个个手动地写,那将是相当的麻烦的。因此,pkg-config就应运而生了。pkg-config能够把这些头文件和库文件的位置指出来,给编译器使用。pkg-config主要提供了下面几个功能:

  • 检查库的版本号。 如果所需要的库的版本不满足要求,它会打印出错误信息,避免链接错误版本的库文件
  • 获得编译预处理参数,如宏定义、头文件的位置
  • 获得链接参数,如库及依赖的其他库的位置,文件名及其他一些链接参数
  • 自动加入所依赖的其他库的设置

pkg-config能够把这些头文件和库文件的位置指出来,给编译器使用。如果你的系统装有libdrm,可以尝试一下下面的命令$pkg-config --cflags libdrm。可以看到其输出是gtk的头文件的路径。

我们平常都是这样用pkg-config的。

$gcc main.c `pkg-config --cflags --libs libdrm` -o main$pkg-config --cflags --libs libdrm
-I/usr/local/include -I/usr/local/include/libdrm -L/usr/local/lib -ldrm

上面的编译命令中,`pkg-config --cflags --libs libdrm`的作用就如前面所说的,把gtk的头文件路径和库文件列出来,让编译去获取。–cflags和–libs分别指定头文件和库文件。

命令中的`不是引号,而是数字1左边那个键位的那个符号。

其实,pkg-config同其他命令一样,有很多选项,不过我们一般只会用到–libs和–cflags选项。

$pkg-config --help
Usage:pkg-config [OPTION?]Help Options:-h, --help                              Show help optionsApplication Options:--version                               output version of pkg-config--modversion                            output version for package--atleast-pkgconfig-version=VERSION     require given version of pkg-config--libs                                  output all linker flags--static                                output linker flags for static linking--short-errors                          print short errors--libs-only-l                           output -l flags--libs-only-other                       output other libs (e.g. -pthread)--libs-only-L                           output -L flags--cflags                                output all pre-processor and compiler flags--cflags-only-I                         output -I flags--cflags-only-other                     output cflags not covered by the cflags-only-I option--variable=NAME                         get the value of variable named NAME--define-variable=NAME=VALUE            set variable NAME to VALUE--exists                                return 0 if the module(s) exist--print-variables                       output list of variables defined by the module--uninstalled                           return 0 if the uninstalled version of one or more module(s) or their dependencies will be used--atleast-version=VERSION               return 0 if the module is at least version VERSION--exact-version=VERSION                 return 0 if the module is at exactly version VERSION--max-version=VERSION                   return 0 if the module is at no newer than version VERSION--list-all                              list all known packages--debug                                 show verbose debug information--print-errors                          show verbose information about missing or conflicting packages (default unless --exists or --atleast/exact/max-version given on the command line)--silence-errors                        be silent about errors (default when --exists or --atleast/exact/max-version given on the command line)--errors-to-stdout                      print errors from --print-errors to stdout not stderr--print-provides                        print which packages the package provides--print-requires                        print which packages the package requires--print-requires-private                print which packages the package requires for static linking--validate                              validate a package's .pc file--define-prefix                         try to override the value of prefix for each .pc file found with a guesstimated value based on the location of the .pc file--dont-define-prefix                    don't try to override the value of prefix for each .pc file found with a guesstimated value based on the location of the .pc file--prefix-variable=PREFIX                set the name of the variable that pkg-config automatically sets
3.2.1 pkg-config配置环境变量

事实上,pkg-config只是一个工具,所以不是你安装了一个第三方库,pkg-config就能知道第三方库的头文件和库文件的位置的。为了让pkg-config可以得到一个库的信息,就要求库的提供者提供一个.pc文件。默认情况下,比如执行如下命令:

# pkg-config --libs --cflags glib-2.0
-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0

pkg-config会到/usr/lib/pkconfig/目录下去寻找glib-2.0.pc文件。也就是说在此目录下的.pc文件,pkg-config是可以自动找到的。然而假如我们安装了一个库,其生成的.pc文件并不在这个默认目录中的话,pkg-config就找不到了。此时我们需要通过PKG_CONFIG_PATH环境变量来指定pkg-config还应该在哪些地方去寻找.pc文件。

我们可以通过如下命令来设置PKG_CONFIG_PATH环境变量:

# export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig/

这样pkg-config就会在/usr/local/lib/pkgconfig/目录下寻找.pc文件了。另外还需要注意的是,上述环境变量的设置只对当前的终端窗口有效。为了让其永久生效,我们可以将上述命令写入到/etc/bash.bashrc等文件中(配置环境变量有很多方法,不止这一种),以方便后续使用。


3.3 pc文件是个什么东东?

pc文件是个什么东东,这里我用一句话来概括就是pkg-config用来在PKG_CONFIG_PATH查找库相关依赖的,一种特殊格式文件!既然是OpenHarmony系统,这里我们就以OpenHarmony下开源mesa3d里面的pc文件为例来举例说明:

$pwd
/home/xxx/xxx/third_party/mesa3d
$cat ohos/pkgconfig_template/zlib.pc 
prefix=ohos_project_directory_stub
exec_prefix=${prefix}
libdir=${prefix}/out/ohos-arm-release/obj/third_party/zlib
sharedlibdir=${libdir}
includedir=${prefix}/third_party/zlibName: zlib
Description: zlib compression library
Version: 1.2.12Requires:
Libs: -L${libdir} -L${sharedlibdir} -lz

下面我们简单描述一下pc文件中的用到的一些关键词:

  • Name: 一个针对library或package的便于人阅读的名称。这个名称可以是任意的,它并不会影响到pkg-config的使用,pkg-config是采用pc文件名的方式来工作的。

  • Description: 对package的简短描述

  • URL: 人们可以通过该URL地址来获取package的更多信息或者package的下载地址

  • Version: 指定package版本号的字符串

  • Requires: 本库所依赖的其他库文件。所依赖的库文件的版本号可以通过使用如下比较操作符指定:=,<,>,<=,>=

  • Requires.private: 本库所依赖的一些私有库文件,但是这些私有库文件并不需要暴露给应用程序。这些私有库文件的版本指定方式与Requires中描述的类似。

  • Conflicts: 是一个可选字段,其主要用于描述与本package所冲突的其他package。版本号的描述也与Requires中的描述类似。本字段也可以取值为同一个package的多个不同版本实例。例如: Conflicts: bar < 1.2.3, bar >= 1.3.0

  • Cflags: 编译器编译本package时所指定的编译选项,和其他并不支持pkg-config的library的一些编译选项值。假如所需要的library支持pkg-config,则它们应该被添加到Requires或者Requires.private中

  • Libs: 链接本库时所需要的一些链接选项,和其他一些并不支持pkg-config的library的链接选项值。与Cflags类似

  • Libs.private: 本库所需要的一些私有库的链接选项



1.pkg-config 与.pc文件
2.pkgconfig和环境变量PKG_CONFIG_PATH和PKG_CONFIG_LIBDIR
3.Linux中pkg-config的使用
4.Linux修改环境变量的4种方法


3.4 怎么通过OpenHarmony源码编译ohos-sdk

很简单,如下:

./build/prebuilts_download.sh
./build.sh --product-name ohos-sdk –ccache  --target-cpu arm64


1.Musl-libc库编译

该博客,简单介绍了怎么编译生成musl libc库!
2.OpenHarmony富设备移植指南—开源GPU驱动编译
这篇博客我们并不是学习怎么编译GPU,而是学习musl + clang配置编译

3.aarch64-linux-ohos交叉编译rust
4.ohos_cross_tools交叉编译工具链
5.一文带你读懂如何移植三方库到OpenHarmony

++参考价值不大,已经完全过时了!主要描述了,如何移植第三方库到OH平台,这个可以为后续vivante GPU移植到OH参考使用++

6.基于OpenHarmony的第三方库编译移植环境(arm-linux-ohos平台)
7.交叉编译 Arm64 OHOS(鸿蒙系统)版本
8.OpenHarmony musl交叉编译

这篇博客可以参考,可以怎么使用musl + gcc编译

9.clang交叉编译Android clang交叉编译使用musl库
10.Building Linux with Clang/LLVM

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

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

相关文章

当量化私募投资总监能学到什么?

我的情况更新 ​我是美国电子工程背景毕业的。在华尔街第一份实习是在E3做手工t0的proprietary trading&#xff0c;被刷下来之后就一直在帮顶级的对冲基金打杂当助理。所以当初决定回国一展身手&#xff0c;并且写下了破百万阅读的&#xff1a; 在私募做量化研究半年能学到什…

基于神经网络的偏微分方程求解器再度取得突破,北大字节的研究成果入选Nature子刊

目录 一.引言:神经网络与偏微分方程 二.如何基于神经网络求解偏微分方程 1.简要概述 2.基于神经网络求解偏微分方程的三大方向 2.1数据驱动 基于CNN 基于其他网络 2.2物理约束 PINN 基于 PINN 可测量标签数据 2.3物理驱动(纯物理约束) 全连接神经网路(FC-NN) CN…

保姆级讲解字符串函数(下篇)

目录 strtok的使用 strerror的使用 strstr的使用和函数模拟实现 strstr的使用 strstr函数模拟实现 接上篇&#xff1a;保姆级讲解字符串函数&#xff08;上篇&#xff09;&#xff0c;我们接着把剩下三个函数讲解完&#xff0c;继续跟着我的步伐一起学习呀. strtok的使用 …

从 Language Model 到 Chat Application:对话接口的设计与实现

作者&#xff1a;网隐 RTP-LLM 是阿里巴巴大模型预测团队开发的大模型推理加速引擎&#xff0c;作为一个高性能的大模型推理解决方案&#xff0c;它已被广泛应用于阿里内部。本文从对话接口的设计出发&#xff0c;介绍了业界常见方案&#xff0c;并分享了 RTP-LLM 团队在此场景…

ARM中多寄存内存访问概念和栈的种类和应用

多寄存器内存访问指令 多寄存器内存访问指令 MOV R1,#1 MOV R2,#2 MOV R3,#3 MOV R4,#4 MOV R11,#0x40000020 STM R11,{R1-R4} 将R1-R4寄存器中的数据存储到内存以R11为起始地址的内存中 LDM R11,{R6-R9} 将内存中以R11为起始地址的数据读取到R6-R9寄存器中 当寄存器…

Tensorflow2.0+部署(tensorflow/serving)过程备忘记录Windows+Linux

Tensorflow2.0部署&#xff08;tensorflow/serving&#xff09;过程备忘记录 部署思路&#xff1a;采用Tensorflow自带的serving进模型部署&#xff0c;采用容器docker 1.首先安装docker 下载地址&#xff08;下载windows版本&#xff09;&#xff1a;https://desktop.docke…

基于springboot+vue实现早餐店点餐系统项目【项目源码+论文说明】计算机毕业设计

基于springbootvue实现早餐店点餐系统演示 摘要 多姿多彩的世界带来了美好的生活&#xff0c;行业的发展也是形形色色的离不开技术的发展。作为时代进步的发展方面&#xff0c;信息技术至始至终都是成就行业发展的重要秘密。不论何种行业&#xff0c;大到国家、企业&#xff0…

文件操作上(c语言)

目录 1. 文件的作用2. 什么是文件2.1 程序文件2.2 数据文件2.3 文件名 3. 二进制文件和文本文件4. 文件的打开和关闭4.1 流和标准流4.1.1 流4.1.2 标准流 4.2 文件指针4.3 文件的打开与关闭4.3.1 文件的打开模式4.3.2 实例代码 1. 文件的作用 使用文件可以将数据进行持久化的保…

openssl调试记录

openssl不能直接解密16进制密文&#xff0c;需要把密文转化成base64格式才能解密 调试记录如下&#xff1a;

Qt 中Json文件的操作

Json文件的读取 QFile file("data.json"); //准备好的文件file.open(QIODevice::ReadOnly|QIODevice::Text);QByteArray arr file.readAll();QJsonDocument jsonDoc QJsonDocument::fromJson(arr);QJsonObject jsonObj jsonDoc.object();qint32 id jsonObj["…

Dubbo-记录

1.概念 Apache Dubbo 是一款 RPC 服务开发框架&#xff0c;用于解决微服务架构下的服务治理与通信问题&#xff0c;官方提供了 Java、Golang 等多语言 SDK 实现。使用 Dubbo 开发的微服务原生具备相互之间的远程地址发现与通信能力&#xff0c; 利用 Dubbo 提供的丰富服务治理…

Qt QListwidget与QStackedWidget或QTableWidget实现多界面切换的效果

文章目录 效果图使用QStackedWidget实现使用QTableWidget实现总结 效果图 使用QStackedWidget实现 QStackedWidget提供了一种堆栈式的界面布局方式。功能&#xff1a;QStackedWidget允许开发者在一个固定区域内显示多个子窗口或页面&#xff0c;但同时只显示其中一个子窗口&am…

windows下安装python3.8

一、从官网下载安装包 官网地址&#xff1a;https://www.python.org/downloads/ 华为云地址&#xff1a;https://mirrors.huaweicloud.com/python/ 第三方镜像&#xff1a;https://registry.npmmirror.com/binary.html?pathpython/ 注意&#xff1a;从python3.8.10版本开始…

PostgreSQL索引篇 | Hash索引

Hash索引 PostgreSQL版本为8.4.1 &#xff08;本文为《PostgreSQL数据库内核分析》一书的总结笔记&#xff0c;需要电子版的可私信我&#xff09; 在实际的数据库系统中&#xff0c;除了B-Tree外&#xff0c;还有多种数据结构可做索引&#xff0c;Hash表就是其中的一种。通过…

HTML_CSS_盒子模型

盒子模型组成 内容区域&#xff08;comtent&#xff09;内边距区域&#xff08;padding&#xff09;边框区域&#xff08;border&#xff09;外边距区域&#xff08;margin&#xff09; 布局标签 标签&#xff1a;<div> </div> 和 <span> …

Leetcode笔记——二叉树的迭代遍历

中序遍历&#xff1a; 定义一个 保存中间量的栈 和一个 结果数组 1. 模板写法 注释版&#xff1a; 背诵版&#xff1a; 前序遍历 1. 中 右 左 的顺序遍历 2. 模板写法&#xff0c;按中 左 右 的顺序遍历 后序遍历 1. 模板写法&#xff0c;按左 右 中 的顺序遍历 注释版&am…

FreeRTOS操作系统学习——同步互斥与通信

同步&#xff08;Synchronization&#xff09; 同步是一种机制&#xff0c;用于确保多个任务能够按照特定的顺序协调执行或共享数据。当一个任务需要等待其他任务完成某个操作或满足某个条件时&#xff0c;同步机制可以帮助任务进行协调和等待。 在FreeRTOS中&#xff0c;常见…

Spring官网中查看MongoDB的API文档的详细步骤

目录 Spring官网中查看MongoDB的API文档的详细步骤1、进入 Spring 官网2、选择 Mongodb的文档介绍3、点击API文档4、进入文档查询页面 Spring官网中查看MongoDB的API文档的详细步骤 1、进入 Spring 官网 首先进入Spring的官网&#xff0c;然后点击【Spring Data】 2、选择 Mon…

Java二叉树 (2)

&#x1f435;本篇文章将对二叉树的一些基础操作进行梳理和讲解 一、操作简述 int size(Node root); // 获取树中节点的个数int getLeafNodeCount(Node root); // 获取叶子节点的个数int getKLevelNodeCount(Node root,int k); // 获取第K层节点的个数int getHeight(Node r…

P1958 上学路线

难度&#xff1a;普及- 题目描述 你所在城市的街道好像一个棋盘&#xff0c;有 a 条南北方向的街道和 b 条东西方向的街道。南北方向的 a 条街道从西到东依次编号为 1 到 a&#xff0c;而东西方向的 b 条街道从南到北依次编号为 1 到 b&#xff0c;南北方向的街道 i 和东西方…