HarmonyOS compiles open source native library (OpenSSL example)

Preface

Recently, the project will start working on the Hongmeng version, and some codes that rely on native also need to be migrated. A certain native module depends on openssl, and openssl needs to be recompiled under Hongmeng. At the beginning, I searched a lot of relevant documents but couldn't find the method. I had no choice but to try it slowly based on my experience, and finally succeeded.

Hongmeng NDK download address

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

You need to download a separate sdk because the ndk in the sdk downloaded from the ide is incomplete and lacks sysroot.

How to compile

Use Cmake

The above download address actually contains a tutorial for compiling third-party libraries, but it is only based on Cmake and is very crude. It does not provide a real tutorial for compiling third-party libraries. In actual development, it is usually much more complicated and requires Compiled libraries often have many configurations and sub-dependencies, which are difficult to handle. In addition, some libraries do not provide Cmake compilation method at all, such as OpenSSL. If the library supports it, it is relatively simple to compile using cmake. You can use cmake-gui or ide.

Use other compilation methods provided by the library

Most libraries will provide a configuration script (./Configure) for users to customize their compilation. Usually, they only need to configure some necessary parameters and the paths to the necessary tools, but now mainstream libraries definitely do not have Hongmeng support. , so there are many additional things that need to be configured by yourself. Next, take compiling OpenSSL as an example.

First define a more general configuration scriptbuild_config.sh, so that it can be used when compiling other libraries in the future. Hongmeng’s compiler does not seem to Like Android, you need to distinguish between API and architecture. They are all in the llvm directory and can be specified directly

In addition, you need to specify the target platform target, sysroot, and cflags. I did not find it in the document. I found it in the sdk as usualohos.toolchain.cmake file, defined with reference to this file

What is more troublesome is that you need to specify the architecture when compiling openssl. The architecture configuration supported by openssl is defined in the files below. However, without Hongmeng support, you can only use linux, linux-armv4, linux-aarch64, etc.

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

The next step is relatively simple. Then define a script build_openssl.sh that performs compilation. The optional compilation parameters are in the configure file and can be configured as needed.

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 ..

There are two more pitfalls

  1. Openssl under armv7 architecture relies on libatomic, but this library is not provided in Hongmeng SDK, so I directly changed the configuration in openssl. The linux-armv4 configuration was originally inherited from linux -latomic, which relies on libatomic, is directly changed to inherit linux-generic32. libatomic is a library that maintains atomicity under multi-threading, so no-threads needs to be added to disable multi-threading. In addition, you can also compile a libatomic yourself and link it together, so that you can use multi-threading .

image

  1. The so library compiled with the default configuration has soft links. There are names like so.x.y with version numbers, which also need to be changed in the configuration.

image

Finally, just put the script file in the openssl directory and compile it. You can also write another script to compile all the architectures at once.

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

Guess you like

Origin blog.csdn.net/qq_39312146/article/details/134935197