arm平台编译so文件回顾
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、几个点
- 二、回顾过程
- 1.上来就执行Makefile
- 2.编译第三方开源库.a文件
- 2.1 build.sh脚本
- 2.2 Makefile
- 3.最终编译
- 三、其它知识点
- 总结
前言
提示:这里可以添加本文要记录的大概内容:
在编译arm平台so文件时,完成了以下的几个点:
1、根据第三方开源的build.sh文件编译第三方开源库,至于build.sh文件怎么写,大概是看开源仓的README文件吧。
2、写了一个MakeFile文件并运行编译了.a文件。最近查资料的时候获取到一个知识点就是,其实.a就是所有.o文件的集合。
3、根据子文件夹Makefile文件编译子文件夹.a文件。
4、解决编译过程中的多个问题
一、几个点
1、目标
在arm机器上编译出arm平台上可用的so文件
2、机器系统
[root@ncn4a-mapopenservice-34-12-242 ~]# uname -a
Linux ncn4a-mapopenservice-34-12-242 4.19.36-vhulk1907.1.0.h1393.eulerosv2r8.aarch64 #1 SMP Thu Jan 5 17:52:22 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux
3、build.sh和Makefile领悟
接前言。现在理解了build和Makefile的区别。源于我将makefile的文件内容放在了build.sh脚本中。然后感觉突然恍然大悟。
Makefile文件是用来编译代码的。里面是有CXXFLAGS,就是将.c//cpp文件编译成.a文件。
OBJ关键词就要编译成.a还是.so文件格式。
而build.sh文件其实就是linux指令集合文件,里面写了编译库的很多指令。其中就包括调用makefile的一步,即调用make指令。
所以build.sh和makefile是有比较大的区别的。
而且自己写的代码只需要编写Makefile就可以了,即只需要Makefile就可以了。因为用不到第三方开源库的.configure、make install。只需要一个make就可以了,所以写个make就可以执行了。
二、过程回顾
1.上来就执行Makefile
拿到studio_compile工程后,以为是直接执行build就可以了。但是执行时报了一个文件格式不对的错误
[2023-12-06 16:38:38] [root@ncn4a-mapopenservice-34-12-242 compile_wrapper]# ll
[2023-12-06 16:38:39] total 16
[2023-12-06 16:38:39] drwxrwxr-x 2 root root 4096 Apr 27 2023 include
[2023-12-06 16:38:39] -rw-rw-r-- 1 root root 1926 Apr 27 2023 Makefile
[2023-12-06 16:38:39] drwxrwxr-x 2 root root 4096 Apr 27 2023 src
[2023-12-06 16:38:39] drwxrwxr-x 2 root root 4096 Apr 27 2023 vs
[2023-12-06 16:38:39] [root@ncn4a-mapopenservice-34-12-242 compile_wrapper]# make -jm98
[2023-12-06 16:38:47] g++ -Werror=return-type -std=c++0x -Wl,-z,relro,-z,now,-z,noexecstack -D_FORTIFY_SOURCE=2 -O2 -s -ftrapv -fPIC -fstack-protector-all -w -c -shared -o -D__STDC_LIMIT_MACROS -Dlinux -I. -I./include -I../model/include -I../common/include -I../compiler/include -I../configurator/include -I../operation/include -I../preprocessor/include -I../pbencoder/include -I../../../3rd/gdal/include/linux -I../../../3rd/gdal/src/libtiff\include -I../../../3rd/boost/include -I../../../3rd/jni/include/linux -I../../../3rd/protobuf/include -I../../../3rd/sqlite/include -I../../../3rd/zlib/include/linux -I../../../platform/HuaweiSecureC/include src/com_huawei_mobilegis_data_studiocompile_engine_NativeEngine.cpp -o src/com_huawei_mobilegis_data_studiocompile_engine_NativeEngine.o
[2023-12-06 16:38:47] g++ -Werror=return-type -std=c++0x -Wl,-z,relro,-z,now,-z,noexecstack -D_FORTIFY_SOURCE=2 -O2 -s -ftrapv -fPIC -fstack-protector-all -w -c -shared -o -D__STDC_LIMIT_MACROS -Dlinux -I. -I./include -I../model/include -I../common/include -I../compiler/include -I../configurator/include -I../operation/include -I../preprocessor/include -I../pbencoder/include -I../../../3rd/gdal/include/linux -I../../../3rd/gdal/src/libtiff\include -I../../../3rd/boost/include -I../../../3rd/jni/include/linux -I../../../3rd/protobuf/include -I../../../3rd/sqlite/include -I../../../3rd/zlib/include/linux -I../../../platform/HuaweiSecureC/include src/CompileLayerWrapper.cpp -o src/CompileLayerWrapper.o
[2023-12-06 16:38:47] g++ -Werror=return-type -std=c++0x -Wl,-z,relro,-z,now,-z,noexecstack -D_FORTIFY_SOURCE=2 -O2 -s -ftrapv -fPIC -fstack-protector-all -w -c -shared -o -D__STDC_LIMIT_MACROS -Dlinux -I. -I./include -I../model/include -I../common/include -I../compiler/include -I../configurator/include -I../operation/include -I../preprocessor/include -I../pbencoder/include -I../../../3rd/gdal/include/linux -I../../../3rd/gdal/src/libtiff\include -I../../../3rd/boost/include -I../../../3rd/jni/include/linux -I../../../3rd/protobuf/include -I../../../3rd/sqlite/include -I../../../3rd/zlib/include/linux -I../../../platform/HuaweiSecureC/include src/ParseJNIObj.cpp -o src/ParseJNIObj.o
[2023-12-06 16:38:47] g++ -Wl,-z,relro,-z,now,-z,noexecstack -D_FORTIFY_SOURCE=2 -O2 -s -ftrapv -fPIC -fstack-protector-all -static-libstdc++ -shared -o libcompile_wrapper.so ./src/com_huawei_mobilegis_data_studiocompile_engine_NativeEngine.o ./src/CompileLayerWrapper.o ./src/ParseJNIObj.o -L../../../build/lib/linux -lcompiler -lconfigurator -lpreprocessor -lpbencoder -loperation -lcommon -L../../../3rd/gdal/lib/linux -lgdal -lgeos_c -lgeos -lproj -ljson-c -L../../../3rd/boost/lib/linux -lboost_serialization -lboost_filesystem -lboost_system -lboost_thread -L../../../3rd/protobuf/lib/linux -lprotobuf -L../../../3rd/sqlite/lib/linux/ -lsqlite3 -L../../../3rd/zlib/lib/linux/ -lz -L../../../3rd/gdal/src/libtiff/lib -ltiff -L../../../platform/HuaweiSecureC/lib/linux/ -lsecurec -ldl -lpthread
[2023-12-06 16:39:02] /usr/bin/ld:../../../3rd/gdal/lib/linux/libgdal.a: file format not recognized; treating as linker script
[2023-12-06 16:39:02] /usr/bin/ld:../../../3rd/gdal/lib/linux/libgdal.a:1: syntax error
[2023-12-06 16:39:02] collect2: error: ld returned 1 exit status
[2023-12-06 16:39:02] make: *** [Makefile:43: all] Error 1
即这一条:
/usr/bin/ld:../../../3rd/gdal/lib/linux/libgdal.a: file format not recognized; treating as linker script
然后就查看一下libgdal.a文件格式,使用file (filename)指令
[2023-12-06 17:41:48] [root@ncn4a-mapopenservice-34-12-242 linux]# file libgdal.a
[2023-12-06 17:41:58] libgdal.a: ASCII text
[2023-12-06 17:41:58] [root@ncn4a-mapopenservice-34-12-242 linux]# timed out waiting for input: auto-logout
这个显示情况其实还看不出来文件格式。这个ACII text文件其实是因为.a文件在windows环境下解压导致文件格式出问题了。但是其实正常的,也会是x86的格式,不是arm的格式。总而言之,就是报错格式不对。
这个文件是第三方开源库静态库文件,所以需要编译第三方开源静态库。
其实后来按照心哥的说法,即便格式没有变成ASCII码也是需要重新编译第三方开源库的,因为平台变了,之前的.a文件是x86格式的。
这边不得不吐槽,上传到git上的.a文件真是一点用没有啊。
2、编译第三方开源库.a文件
先后编译boost库、protobuf、sqlite、zlib、gdal库。其中有两个点需要单独领出来看。一个就是gdal库,还有一个就是没有Makefile然后我自己写的makefile文件编译的。
先说gdal库。gdal需要依赖tiff库、json-c库、geos库、proj库,最后才是安装gdal库。这边也是这次才理解的就是。就是对于这几个库,自己感觉是编译,其实也是在机器上安装这个库。可以用-- v查看版本号的。
然后这几个开源库用的build.sh脚本编译的。
2.1 build.sh
build.sh基本格式就是以下形式
PREFIX_INC_PATH=$(cd "$(dirname "$0")";pwd) //获取当前路径
git下载 | 备注 | |
解压 | ||
更改文件夹名(可选) | 可选 | |
进入含有configure文件的文件夹中 | ||
执行./configure | --prefix=【】,//设置安装路径 | |
--enable-xxx / --disable-xxx | 不懂 | |
--with-xxx / --without-xxx | 不懂 | |
--build=arm-linux //设置编译环境 | 国产arm机器需要设置平台环境,不然会configure失败,导致build.sh失败 | |
SQLITE3_CFLAGS=路径 | 不懂 | |
SQLITE3_LIBS=路径 -lsqlite3 | 不懂 | |
sh autogen.sh / autoreconf | 不懂,但是要安装autoconf全家桶,可以参考本人帖子 | |
make -j8 | ||
make install | ||
移动OBJ文件 | 可选 | |
【完成】 |
2.2 Makefile
Makefile的格式大概如下
CXXFLAGS= | 用于将.c或.cpp文件编译成.o文件,编译格式为 $(CXX) $(CXXFLAGS) $*.cpp -o $@ | |
CXX= | CXX = xxx指定编译器 | |
搜到这个帖子说的比较详细:Linux Makefile入门总结-CSDN博客
看完这个贴子,增加了对以下几个知识点的了解
元素 | 说明 | 备注 |
目标文件 : 依赖文件 [TAB]命令 | [TAB]:是你键盘左边tab键 | |
-c | -c 是生成 .o 文件的必要参数! | gcc -c main.c -o main.o |
.PHONY: clean | 用来屏蔽同名clean的文件夹或文件 | |
= :变量(可修改) += :追加 := :常量(不可修改) | TARGET = test CXX := g++ | |
$(TARGET) | # 相当于C语言的宏定义 | |
%c、%cpp、%o | 隐含规则: 任意的.c 或 任意的.cpp 或 任意的.o | 使用%c 或 %cpp 或 %o 或 %h 时,优先加点'.'使用,如:%.c、%.cpp、%.o、%.h |
*.c、*.cpp、*.o | 所有的.c 或 所有的.cpp 或 所有的.o | |
$^ | 所有的依赖文件 依赖文件:我要做这个操作,依赖哪些东西 | $(TARGET): $(OBJ) $(CXX) $^ -o $@ |
$< | 所有依赖文件的第一个文件(应该也是最匹配的一个文件) | %.o: %cpp $(CXX) $(CXXFLAGS) $< -o $@ |
$@ | 所有的目标文件 目标文件:我要做这个操作,要生成的东西; | |
CXXFLAGS | CXXFLAGS = -c -Wall 类似于宏替换 | |
SRC = $(wildcard *.cpp) | 获取项目路径下的所有.cpp源文件 | |
OBJ = $(patsubst %.cpp, %.o, $(SRC)) | 根据源文件链接成 .o 文件 | wildcard 和 patsubst 是Makefile函数的用法 |
-wall | 编译后显示所有警告 | Makefile 中 -g、-o、-c、-f 、-D、-Wall、-L、含义 | 码农家园 |
这个帖子绝佳,搞明白很多之前的疑问,赞!Makefile 中 -g、-o、-c、-f 、-D、-Wall、-L、含义 | 码农家园
3、最终编译
继续回顾流程,显示用各个开源库的build.sh脚本把各个开源库编译一遍。再把子文件夹用Makefile编译一遍,这个上面的帖子也说了,每个子文件夹都有一个Makefile
这其中还有一个很奇怪的一个点,就是工程写了一个build.sh脚本,是进入每个子文件夹分别执行Makefile,这个也是一个知识点。但这不是重点,重点是用这个build.sh脚本执行编译时,过程中会因为MobaXterm出现network断开导致编译失败,所以我是对子文件夹单独编译的。可以编好。就很奇怪。
到此第三方开源库、子文件的静态库都编好了。其中过程中遇到好几个问题,通过百度都解决了,也记录在自己的文章中了。报错处理集-CSDN博客,现在就开始编译最终的so文件了。
这其中还有一个知识点就是,其实我之前理解的所谓交叉编译环境是在x86机器上安装检查编译工具。但是过程中问了心哥知道其实我用的这个欧拉系统是arm环境,所以交叉编译是不是只能用arm机器呢,这个问题留存解决。
解释:百度了一下,理解了,意思就是交叉编译是因为目标平台可能不支持编译或者资源不够,跨平台编译就叫交叉编译。如果像我这样就不算交叉编译了吧。
【百度百科:
一个经常会被问到的问题就是,“既然我们已经有了主机编译器,那为什么还要交叉编译呢?”其实答案很简单。有时是因为目的平台上不允许或不能够安装我们所需要的编译器,而我们又需要这个编译器的某些特征;有时是因为目的平台上的资源贫乏,无法运行我们所需要编译器;有时又是因为目的平台还没有建立,连操作系统都没有,根本谈不上运行什么编译器。
另一个经常会被问到的问题就是:“既然可以交叉编译,那还要主机编译干吗?”其实答案也很简单,交叉编译是不得已而为之!与主机编译相比,交叉编译受的限制更多,虽然在理论上我们可以做任何形式的交叉编译,但事实上,由于受到专利、版权、技术的限制,并不总是能够进行交叉编译,尤其是在业余条件下!举例来说,我们至今无法生成惠普公司专有的som格式的可执行文件,因此我们根本无法做目的平台为HPPA-HPUX的交叉编译。来源:交叉编译_百度百科】
还有一点就是这次编译过程比较复杂,一方面是因为集气室离线的,很多是要离线安装的。但是问了心哥,说可以用yum install在线安装,试了确实可以。这个可能跟是欧拉系统有关。
三、其他知识点
1、这边还有一个关于x86和arm平台区别的知识点,找到这篇帖子:https://www.cnblogs.com/kin-zhang/p/15031633.html
2、Makefile里面可以直接把.a换成.so吗?编译.a和编译.so的Makefile有什么区别?
这个需要后面了解下
Makefile链接静态库.a编译成动态库.so_makefile 链接.a-CSDN博客
3、linux安装git的用户设置
当时准备安装git拉取代码的,不过发现并不可行,所以没有深究下去。后面可以了解下。
4、LIB = ar cr什么意思,未知,后面要了解下
总结
对整个编译过程进行了总结,是有意义的,编成功了。但是经验不复用应该是不好的,需要把经验积累下来。突然想起来强哥之前一直说要经验复用,大概也是指的这个意思吧。
相关文章:

arm平台编译so文件回顾
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、几个点二、回顾过程 1.上来就执行Makefile2.编译第三方开源库.a文件 2.1 build.sh脚本2.2 Makefile3.最终编译三、其它知识点总结 前言 提示:这…...

【数据结构】顺序表的定义和运算
目录 1.初始化 2.插入 3.删除 4.查找 5.修改 6.长度 7.遍历 8.完整代码 🌈嗨!我是Filotimo__🌈。很高兴与大家相识,希望我的博客能对你有所帮助。 💡本文由Filotimo__✍️原创,首发于CSDN📚。 &…...

idea使用maven的package打包时提示“找不到符号”或“找不到包”
介绍:由于我们的项目是多模块开发项目,在打包时有些模块内容更新导致其他模块在引用该模块时不能正确引入。 情况一:找不到符号 情况一:找不到包 错误代码部分展示: Failure to find com.xxx.xxxx:xxx:pom:0.5 in …...
MetricBeat监控MySQL
目录 一、安装部署 二、开启mysql监控模块 三、编辑mysql配置文件 四、启动Metricbeat 五、查看监控图表 一、安装部署 metriceat的安装部署参考章节: Metricbeat安装使用,这里不再赘述。 二、开启mysql监控模块 进入metricbeat安装目录 ./metricb…...

Child Mind Institute - Detect Sleep States(2023年第一次Kaggle拿到了银牌总结)
感谢 感谢艾兄(大佬带队)、rich师弟(师弟通过这次比赛机械转码成功、耐心学习)、张同学(也很有耐心的在学习),感谢开源方案(开源就是银牌),在此基础上一个月…...

Esxi7Esxi8设置VMFSL虚拟闪存的大小
Esxi7Esxi8设置VMFSL虚拟闪存的大小 ESXi7,8 默认安装会分配一个 VMFSL(VMFS-L)(Local VMFS)很大空间(120G), 感觉很浪费, 实际给 8G 就可以了, 最少 6G , 经实验,给2G没法安装 . Esxi7是虚拟闪存的 修改的方法是: 在安装时修改 设置 autoPartitionOSDataSize8192 在cdromBoo…...

vue2+electron桌面端一体机应用
vue2+electron项目 前言:公司有一个项目需要用Vue转成exe,首先我使用vue-cli脚手架搭建vue2项目,然后安装electron 安装electron 这一步骤可以省略,安装electron-builder时会自动安装electron npm i electron 安装electron-builder vue add electron-builder 项目中多出…...

目标检测——OverFeat算法解读
论文:OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks 作者:Pierre Sermanet, David Eigen, Xiang Zhang, Michael Mathieu, Rob Fergus, Yann LeCun 链接:https://arxiv.org/abs/1312.6229 文章…...
vue获取主机id和IP地址
获取主机id和IP地址 在vue.config.js const os require(“os”); function getNetworkIp() { let needHost “”; // 打开的host try { // 获得网络接口列表 let network os.networkInterfaces(); for (let dev in network) { let iface network[dev]; for (let i 0; i …...

在pytorch中自定义dataset读取数据
这篇是我对哔哩哔哩up主 霹雳吧啦Wz 的视频的文字版学习笔记 感谢他对知识的分享 有关我们数据读取预训练 以及如何将它打包成一个一个batch输入我们的网络的 首先我们来看一下之前我们在讲resnet网络时所使用的源码 我们去使用了官方实现的image folder去读取我们的图像数据 然…...

ConvNeXt V2: Co-designing and Scaling ConvNets with Masked Autoencoders
1.关于稀疏卷积的解释:https://zhuanlan.zhihu.com/p/382365889 2. 答案: 在深度学习领域,尤其是计算机视觉任务中,遮蔽图像建模(Masked Image Modeling, MIM)是一种自监督学习策略,其基本思想…...
Java后端的登录、注册接口是怎么实现的
目录 Java后端的登录、注册接口是怎么实现的 Java后端的登录接口是怎么实现的 Java后端的注册接口怎么实现? 如何防止SQL注入攻击? Java后端的登录、注册接口是怎么实现的 Java后端的登录接口是怎么实现的 Java后端的登录接口的实现方式有很多种&a…...
TCP Keepalive 和 HTTP Keep-Aliv
HTTP的Keep-Alive 在http1.0的版本中,它是基于请求-应答模型和TCP协议的,也就是在建立TCP连接后,客户端发送一次请求并且接收到响应后,就会立马断开TCP连接,称为HTTP短连接,这种方式比较耗费时间以及浪费资…...
操作系统 复习笔记
操作系统的目标和作用 操作系统的目标 1.方便性 2.有效性 3.可扩展性 4.开放性 操作系统的作用 1.OS作为用户与计算机硬件系统之间的接口 2.OS作为计算机系统资源的管理者 3.OS实现了对计算机系统资源的抽象 推动操作系统发展的主要动力 1.不断提高计算机系统资源的…...
Java中实现单例模式的方式
1. 使用静态内部类实现单例模式 在Java中,使用静态内部类实现单例模式是一种常见而又有效的方式。这种方式被称为“静态内部类单例模式”或者“Holder模式”。这种实现方式有以下优点: 懒加载(Lazy Initialization):静…...

Vue3-01-创建项目
环境准备 1.需要用到 16.0 以及更高版本的 node.js 2.使用vscode编辑器进行项目开发可以在命令行中查看node的版本号: node -v创建项目 1.准备一个目录 例如,我创建项目的时候是在该目录下进行的;D:\projectsTest\vue3project2.执行创建命令(*&#x…...

Go 语言中的反射机制
欢迎大家到我的博客浏览,更好的阅读体验请点击 反射 | YinKais Blog 反射在大多数的应用和服务中并不常见,但是很多框架都依赖 Go 语言的反射机制简化代码。<!--more-->因为 Go 语言的语法元素很少、设计简单,所以它没有特别强的表达能…...
[leetcode 前缀和]
525. 连续数组 M :::details 给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。 示例 1: 输入: nums [0,1] 输出: 2 说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。示例 2: 输入: nums [0,1,0] 输出: …...

Python与ArcGIS系列(十五)根据距离抓取字段
目录 0 简述1 实例需求2 arcpy开发脚本0 简述 在处理gis数据的时候,会遇到这种需求:将一个图层与另一个图层中相近的要素进行字段赋值。本篇将介绍如何利用arcpy及arcgis的工具箱实现这个功能。 1 实例需求 为了介绍这个功能的实现,我们需要有一个特定的功能需求。在这里选…...
YOLOv8分割训练及分割半自动标注
YOLOv8是基于目标检测算法YOLOv5的改进版,它在YOLOv5的基础上进行了优化和改进,加入了一些新的特性和技术,如切片注意力机制、骨干网络的选择等。 本文以yolov8-seg为基准,主要整理分割训练流程及使用v8分割模型进行半自动标注的过程。 一、v8-seg训练 1.1 环境配置 github…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...