HarmonyOS编译开源native库(OpenSSL实例)

前言

近期项目要开始做鸿蒙版本,有一部分依赖native的代码也需要迁移,某个native模块依赖openssl,需要在鸿蒙下重新编译openssl才行。一开始找了很多相关文档都没有得到方法,无奈只能自己凭经验慢慢试,最后还是成功了。

鸿蒙NDK下载地址

https://gitee.com/openharmony/docs/tree/master/zh-cn/release-notes#openharmony-release-notes

需要单独下载一份sdk,因为ide里面下载的sdk里面的ndk是不全的,缺少sysroot

如何编译

使用Cmake

上面的下载地址其实包含了编译三方库的教程,但是只有基于Cmake的方式,而且非常简陋,并没有提供一个真实的三方库编译教程,而实际开发中通常要复杂很多,需要编译的库往往有许多配置,还有一些子依赖,比较难以处理。另外有些库压根没有提供Cmake编译的方式,比如OpenSSL。如果库支持的话使用cmake编译相对简单一些,可以使用cmake-gui或者ide。

使用库提供的其他编译方式

大多数库都会提供一个配置脚本(./Configure)让使用者自定义进行编译,通常只需要配置好一些必要参数,必要工具的路径就可以比较轻松的完成,但是现在主流库肯定是没有鸿蒙支持的,所以需要自己额外配置的东西很多,接下来以编译OpenSSL为例。

先定义一个比较通用的配置脚本build_config.sh,方便以后编译其他库也能用,鸿蒙的编译器好像不像android那样需要区分api和架构,全都在llvm目录下,直接指定就可以了

另外还需要指定目标平台target、sysroot、cflags这些,我在文档里面没有找到,按照惯例找到了sdk里面的ohos.toolchain.cmake文件,参考这个文件进行了定义

比较麻烦的是编译openssl时需要指定的架构,openssl支持的架构配置在下图这些文件里面给了定义,但是没有鸿蒙的支持,那就只能选用linux的,linux-armv4、linux-aarch64这些。

image

build_config.sh

 #NDK路径export OHOS_NATIVE_HOME=/Users/admin/Downloads/ohos-sdk/darwin/nativeexport PATH=$OHOS_NATIVE_HOME/llvm/bin:$PATH#cpu架构if [ "$#" -lt 1 ]; thenTHE_ARCH=armv7elseTHE_ARCH=$(tr [A-Z] [a-z] <<< "$1")fiBASE_FLAGS="--sysroot=$OHOS_NATIVE_HOME/sysroot -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wa,--noexecstack -fPIC"#根据不同架构配置环境变量case "$THE_ARCH" inarmv7a|armeabi-v7a)OHOS_ARCH="armeabi-v7a"OHOS_TARGET="arm-linux-ohos"OPENSSL_ARCH="linux-armv4"FF_EXTRA_CFLAGS="--target=$OHOS_TARGET $BASE_FLAGS -march=armv7a"FF_CFLAGS="--target=$OHOS_TARGET $BASE_FLAGS -march=armv7a";;armv8|armv8a|aarch64|arm64|arm64-v8a)OHOS_ARCH="arm64"OHOS_TARGET="aarch64-linux-ohos"OPENSSL_ARCH="linux-aarch64"FF_EXTRA_CFLAGS="--target=$OHOS_TARGET $BASE_FLAGS"FF_CFLAGS="--target=$OHOS_TARGET $BASE_FLAGS";;x86_64|x64)OHOS_ARCH="x86_64"OHOS_TARGET="x86_64-linux-ohos"OPENSSL_ARCH="linux-x86_64"FF_EXTRA_CFLAGS="--target=$OHOS_TARGET $BASE_FLAGS"FF_CFLAGS="--target=$OHOS_TARGET $BASE_FLAGS";;*)echo "ERROR: Unknown architecture $1"[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1;;esac# 工具链TOOLCHAIN=$OHOS_NATIVE_HOME/llvm# 交叉编译库搜索路径SYS_ROOT=$OHOS_NATIVE_HOME/sysroot# 编译器CC=$TOOLCHAIN/bin/clangCXX=$TOOLCHAIN/bin/clang++# 链接器,将目标文件(包括静态库和共享库)合并成一个可执行文件或共享库LD=$TOOLCHAIN/bin/ld-lld# 汇编器,将汇编语言代码转换为机器代码AS=$TOOLCHAIN/bin/llvm-as# 静态库管理工具,用于创建、修改和提取静态库中的目标文件AR=$TOOLCHAIN/bin/llvm-ar# 符号表工具,用于显示目标文件中的符号(函数、变量等)信息NM=$TOOLCHAIN/bin/llvm-nm# 静态库索引工具,用于创建和更新静态库的索引,以提高库的访问速度RANLIB=$TOOLCHAIN/bin/llvm-ranlib# 剥离工具,用于从可执行文件或共享库中去除调试信息,从而减小文件大小STRIP=$TOOLCHAIN/bin/llvm-strip

接下来就比较简单了,再定义一个执行编译的脚本build_openssl.sh,可选的编译参数在configure文件里面,可以按需要配置

image

build_openssl.sh

  #!/bin/bashARCH=$1source build_config.sh $ARCHLIBS_DIR=$(cd `dirname $0`; pwd)/libs/opensslPREFIX=$LIBS_DIR/$OHOS_ARCHecho "PREFIX"=$PREFIXexport CC="$CC"export CXX="$CXX"export CXXFLAGS=$FF_EXTRA_CFLAGSexport CFLAGS=$FF_CFLAGSexport AR="$AR"export LD="$LD"export AS="$AS"export NM="$NM"export RANLIB="$RANLIB"export STRIP="$STRIP"export LDFLAGS="--rtlib=compiler-rt -fuse-ld=lld"./Configure $OPENSSL_ARCH \--prefix=$PREFIX \no-engine \no-asm \no-threads \sharedmake cleanmake -j2make installcd ..

还有两个比较坑的点

  1. armv7架构下openssl依赖了libatomic,但是鸿蒙sdk里面没有提供这个库,所以我直接去改了openssl里面的配置,linux-armv4配置原本继承自linux-latomic,依赖了libatomic,直接改成继承linux-generic32,libatomic是一个多线程下保持原子性的库,所以需要加上no-threads禁用多线程。另外也可以自己去编译一个libatomic出来一起链接,这样就可以用多线程了

image

  1. 默认配置编译出来的so库是带软链接,有so.x.y这种带版本号的命名,也需要在配置里面改一下

image

最后把脚本文件放到openssl目录下执行编译就可以了,也可以再写一个脚本方便一次性编译所有架构

for arch in armeabi-v7a arm64-v8a
dobash build_openssl.sh $arch
done

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

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

相关文章

wvp gb28181 pro 配置https访问

准备工作 必须要有域名。虽然数字证书也有ip证书,但是会很麻烦,多数ca机构验证服务器需要用到80或443端口,也就是必须先备案,所以最好还是使用域名证书。购买域名证书。根据安全级别要求自行配置。单域名(不支持通配符的),阿里云的域名都是可以免费申请的。完成域名到服…

1-存储概念与SAN

任务背景 随着某些业务数据的增大, 公司服务器硬盘空闲空间越来越小, 服务器上也无法再拓展硬盘, 所以我们考虑使用网络存储方式远程共享存储给服务器使用。 任务要求 实现存储通过远程共享给应用服务器使用 任务拆解 1, 需要知道存储有哪些方式可以通过网络共享给服务器使…

【LLM】大模型之RLHF和替代方法(DPO、RAILF、ReST等)

note SFT使用交叉熵损失函数&#xff0c;目标是调整参数使模型输出与标准答案一致&#xff0c;不能从整体把控output质量&#xff0c;RLHF&#xff08;分为奖励模型训练、近端策略优化两个步骤&#xff09;则是将output作为一个整体考虑&#xff0c;优化目标是使模型生成高质量…

使用yum/dnf管理软件包

本章主要介绍使用 yum 对软件包进行管理。 yum 的介绍搭建yum源创建私有仓库yum客户端的配置yum的基本使用使用第三方yum源 使用rpm安装包时经常会遇到一个问题就是包依赖&#xff0c;如下所示。 [rootrhel03 ~]# rpm -ivh /mnt/AppStream/Packages/httpd-2.4.37-41.modulee…

12.10_黑马数据结构与算法笔记Java

目录 058 链表 e10 判环算法1 thinking&#xff1a;什么是空指针&#xff1f; 058 链表 e10 判环算法2 059 数组 e01 合并有序数组1 059 数组 e01 合并有序数组2 060 队列 链表实现1 061 队列 链表实现2 062 队列 环形数组实现 方法1-1 063 队列 环形数组实现 方法1-2…

MySQL使用窗口函数ROW_NUMBER()、DENSE_RANK()查询每组第一名或每组前几名,窗口函数使用详解

MySQL数据表结构 创建 tbl_class_info 表&#xff0c;表中有四个字段 id、username、score、group_name 使用 ROW_NUMBER()、DENSE_RANK() 查询每组前三名 -- 查询每组前3名 SELECT username, score, group_name FROM ( SELECT username, score, group_name, ROW_NUMBER()…

深入理解JVM虚拟机第二十八篇:详解JVM当中方法重写的本质和虚方法表

&#x1f609;&#x1f609; 欢迎加入我们的学习交流群呀&#xff1a; ✅✅1&#xff1a;这是孙哥suns给大家的福利&#xff01; ✨✨2&#xff1a;我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 &#x1f96d;&#x1f96d;3&#xff1a;QQ群&a…

java--Object

1.Object类的作用 Object类是java中所有类的祖宗类&#xff0c;因此&#xff0c;java中所有类的对象都可以直接使用Object类中提供一些方法 2.Object类的常见方法 ①toString存在的意义&#xff1a;toString()方法存在的意义就是为了被子类重写&#xff0c;以便返回对象具体的…

域渗透之DCSYNC攻击

文章目录 Dcsync详解Dcsync原理权限利用条件利用方式mimikatz后门利用使用Empire下的powerview.ps1脚本执行以上三条ACE Dcsync可逆加密存储密码得MachineAccount口令hash的方法使用DCSync导出所有帐户的hash防御 Dcsync详解 在Dcsync没有出现之前&#xff0c;如果攻击者需要拿…

公交站间的距离

&#x1f388; 算法并不一定都是很难的题目&#xff0c;也有很多只是一些代码技巧&#xff0c;多进行一些算法题目的练习&#xff0c;可以帮助我们开阔解题思路&#xff0c;提升我们的逻辑思维能力&#xff0c;也可以将一些算法思维结合到业务代码的编写思考中。简而言之&#…

三翼鸟2023辉煌收官, 定盘2024高质量棋局

最近在不同平台上接连看到这样的热搜话题&#xff1a;用时间胶囊记录2023的自己、2023年度问答、2023十大网络流行语公布… 显然&#xff0c; 2023年进入最后一个月&#xff0c;时间匆匆&#xff0c;这也意味着又到了总结过去和规划未来的时候。拿到结果、取得成绩当然是对202…

12.11作业

1. 完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和密码不匹配&…