arm平台编译so文件回顾

news2024/10/7 12:17:59

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、几个点
  • 二、回顾过程
    • 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什么意思,未知,后面要了解下


总结

        对整个编译过程进行了总结,是有意义的,编成功了。但是经验不复用应该是不好的,需要把经验积累下来。突然想起来强哥之前一直说要经验复用,大概也是指的这个意思吧。

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

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

相关文章

一天一个设计模式---生成器模式

概念 生成器模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;用于构建复杂对象。它允许您逐步构造一个对象&#xff0c;将构建过程与最终对象的表示分离开来。这种模式通常用于创建复杂的对象&#xff0c;这些对象可能有多个部分组成&#xff0c…

MongoDB的插入文档、更新文档语句

本文主要介绍MongoDB的插入文档、更新文档语句。 目录 MongoDB插入文档MongoDB更新文档 MongoDB插入文档 在MongoDB中&#xff0c;可以通过使用insertOne或insertMany方法向集合中插入文档。 insertOne方法可以插入一个文档&#xff0c;例如&#xff1a; db.collection.inse…

条码生成器与Zint使用

文章目录 目的条形码zint支持条形码种类下载编译qt pro配置code保存条形码目的 1: 了解条形码数据理论知识 2: 了解zint第三方库相关, 如何编译引用到项目中 条形码 条形码(Barcode)一维码 和二维码(QR code)都是用于存储信息的图形化表示方式,通常应用于商品标识、库…

LeetCode(52)最小栈【栈】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 最小栈 1.题目 设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void…

【大数据分析】

系列文章目录 文章目录 系列文章目录前言一、数据分析框架二、数据分析方法1.数据清洗&数据探索2.数据清洗之异常值判别3.数据清洗之缺失值处理4.数据探索5.结构优化 三、大数据可视化1.大数据可视化概念1.1 定义1.2 数据可视化的意义 2.可视化类型和模型2.1 科学可视化2.2…

试块二维码制作

记号笔传统方式对试块进行标识&#xff0c;试块表面空间有限能记录的内容不多&#xff0c;标识错误&#xff0c;导致难以辨识&#xff0c;防止混淆和拿错&#xff01;通过个试块进行二维码标识&#xff0c;微信扫码即可了解试块详细信息、生产日期、浇筑部位、强度等信息&#…

【AIGC】大语言模型的采样策略--temperature、top-k、top-p等

总结如下&#xff1a; 图片链接 参考 LLM解码-采样策略串讲 LLM大模型解码生成方式总结 LLM探索&#xff1a;GPT类模型的几个常用参数 Top-k, Top-p, Temperature

python爬取robomaster论坛文章数据,携带登录信息

一. 内容简介 python爬取robomaster论坛文章数据。 二. 软件环境 2.1vsCode 2.2Anaconda version: conda 22.9.0 2.3代码 三.主要流程 3.1 接口分析&#xff0c;以及网页结构分析 # 这是文章链接,其实id就是文章的id # https://bbs.robomaster.com/forum.php?modview…

数据库对象介绍与实践:视图、函数、存储过程、触发器和物化视图

文章目录 一、视图&#xff08;View&#xff09;1、概念2、基本操作1&#xff09;创建视图2&#xff09;修改视图3&#xff09;删除视图4&#xff09;使用视图 3、使用场景4、实践 二、函数&#xff08;Function&#xff09;1、概念2、基本操作1&#xff09;创建函数2&#xff…

一文说清google最新大模型Gemini

随着AI技术的快速发展&#xff0c;谷歌和其他科技巨头在研究和部署上的竞争也越来越激烈。本月12月6号谷歌CEO哈萨比斯在谷歌官网发文&#xff0c;宣布推出万众瞩目的多模态大模型Gemini。标题明晃晃写着“最大”、“最强”&#xff0c;主打的就是一个干爆GPT-4。 一、Gemini的…

公网域名如何解析到内网IP服务器——快解析域名映射外网访问

在本地搭建主机应用后&#xff0c;由于没有公网IP或没有公网路由权限&#xff0c;在需要发布互联网时&#xff0c;就需要用到外网访问内网的一些方案。由于内网IP在外网不能直接访问&#xff0c;通常就用通过外网域名来访问内网的方法。那么&#xff0c;公网域名如何解析到内网…

WordCount 源码解析 Mapper,Reducer,Driver

创建包 com.nefu.mapreduce.wordcount &#xff0c;开始编写 Mapper &#xff0c; Reducer &#xff0c; Driver 用户编写的程序分成三个部分&#xff1a; Mapper 、 Reducer 和 Driver 。 &#xff08; 1 &#xff09; Mapper 阶段 ➢ 用户自定义的 Mapper 要继承自己的父…

Linux,Web网站服务(一)

1.准备工作 为了避免发生端口冲突&#xff0c;程序冲突等现象&#xff0c;建议卸载使用RPM方式安装的httpd [rootnode01 ~]# rpm -e http --nodeps 挂载光盘到/mnt目录 [rootnode01 ~]# mount /dev/cdrom /mnt Apache的配置及运行需要apr.pcre等软件包的支持&#xff0c;因此…

ubuntu20 安装docker

一.官网安装文档 &#xff08;基本按官方文档安装&#xff09; Install Docker Engine on Ubuntu | Docker Docs 二.安装步骤 1.docker 需要64位操作系统、linux内核要在3.1以上 #uname -r 2.卸载可能存在的旧版本 #sudo apt-get remove docker docker-engine docker-ce …

使用STM32 HAL库进行GPIO控制的实例

✅作者简介&#xff1a;热爱科研的嵌入式开发者&#xff0c;修心和技术同步精进&#xff0c; 代码获取、问题探讨及文章转载可私信。 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 &#x1f34e;获取更多嵌入式资料可点击链接进群领取&#xff0c;谢谢支持&#xff01;…

Redis 环境搭建

文章目录 第1关&#xff1a;Redis 环境搭建 第1关&#xff1a;Redis 环境搭建 编程要求 根据上述相关知识&#xff0c;在右侧命令行中完成 Redis 集群的部署与安装。 安装完成后&#xff0c;使用 echo “cluster nodes”|redis-cli -p 7001 -c >/root/test.txt 将结果保存。…

Kubernetes(K8s)数据存储-09

数据存储 在前面已经提到&#xff0c;容器的生命周期可能很短&#xff0c;会被频繁地创建和销毁。那么容器在销毁时&#xff0c;保存在容器中的数据也会被清除。这种结果对用户来说&#xff0c;在某些情况下是不乐意看到的。为了持久化保存容器的数据&#xff0c;kubernetes引…

SpringBoot集成Spring Security+jwt+kaptcha验证(简单实现,可根据实际修改逻辑)

参考文章 【全网最细致】SpringBoot整合Spring Security JWT实现用户认证 需求 结合jwt实现登录功能&#xff0c;采用自带/login接口实现权限控制 熟悉下SpringSecurity SpringSecurity 采用的是责任链的设计模式&#xff0c;是一堆过滤器链的组合&#xff0c;它有一条很…

2013年全国硕士研究生入学统一考试管理类专业学位联考数学试题——解析版

文章目录 2013 级考研管理类联考数学真题一、问题求解&#xff08;本大题共 15 小题&#xff0c;每小题 3 分&#xff0c;共 45 分&#xff09;下列每题给出 5 个选项中&#xff0c;只有一个是符合要求的&#xff0c;请在答题卡上将所选择的字母涂黑。真题&#xff08;2013-01&…

每天学习一点shell系列(2)—函数的参数传递

参考博客&#xff1a;shell 脚本-10函数_eno_zeng的博客-CSDN博客 $n 或 ${n} &#xff1a;函数内使用 $n 或 ${n} 访问对应的参数, 数字代表参数的前后顺序, $1 代表第一个参数, $2 代表第三个参数, $n 代表第n个参数&#xff1b;当n>10时&#xff0c;需要使用${n}来获取参…