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/native
    export PATH=$OHOS_NATIVE_HOME/llvm/bin:$PATH
    #cpu架构
    if [ "$#" -lt 1 ]; then
    	THE_ARCH=armv7
    else
    	THE_ARCH=$(tr [A-Z] [a-z] <<< "$1")
    fi

    BASE_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" in
      armv7a|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/clang
    CXX=$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/bash
    ARCH=$1
    source build_config.sh $ARCH
    LIBS_DIR=$(cd `dirname $0`; pwd)/libs/openssl
    PREFIX=$LIBS_DIR/$OHOS_ARCH

    echo "PREFIX"=$PREFIX

    export CC="$CC"
    export CXX="$CXX"
    export CXXFLAGS=$FF_EXTRA_CFLAGS
    export CFLAGS=$FF_CFLAGS
    export 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 \
    shared

    make clean
    make -j2
    make install

    cd ..

还有两个比较坑的点

  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
do
    bash build_openssl.sh $arch
done
  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在 Android 平台上编译 OpenSSL 静态,需要进行以下步骤: 1. 安装 Android NDK:下载并安装最新版的 Android NDK,然后将其路径添加到环境变量中。 2. 下载 OpenSSL 源代码:从 OpenSSL 官网上下载最新的源代码包,并解压到本地。 3. 配置交叉编译环境:在 OpenSSL 的源代码根目录下,创建一个名为 `setenv-android.sh` 的文件,并将以下内容复制到文件中: ```bash export ANDROID_NDK=/path/to/ndk export API_LEVEL=android-21 export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64 export SYSROOT=$ANDROID_NDK/sysroot export PATH=$TOOLCHAIN/bin:$PATH export CC=armv7a-linux-androideabi$API_LEVEL-clang export CXX=armv7a-linux-androideabi$API_LEVEL-clang++ export AR=llvm-ar export LD=ld.lld export RANLIB=llvm-ranlib export NM=llvm-nm ``` 修改 `ANDROID_NDK` 的值为你本地的 NDK 路径,`API_LEVEL` 的值为你想要编译的 Android API 版本。 4. 执行交叉编译环境配置脚本:在 OpenSSL 的源代码根目录下执行以下命令: ```bash source setenv-android.sh ``` 这会将交叉编译环境配置到当前的 shell 会话中。 5. 配置 OpenSSL 编译选项:在 OpenSSL 的源代码根目录下,执行以下命令: ```bash ./Configure android-armv7 --prefix=/path/to/output/directory ``` 修改 `--prefix` 的值为你想要输出静态的目录路径。 6. 编译静态:在 OpenSSL 的源代码根目录下,执行以下命令: ```bash make && make install ``` 这会编译 OpenSSL 静态,并将其安装到指定的输出目录中。 7. 将静态集成到 Android 项目中:将编译好的 OpenSSL 静态拷贝到你的 Android 项目中,并在 `Android.mk` 文件中添加编译选项,以链接 OpenSSL 静态。 以上是在 Android 平台上编译 OpenSSL 静态的基本步骤,不同版本的 OpenSSL 可能需要微调。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金戈鐡馬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值