libevent之android与鸿蒙编译过程

2024-08-22 23:36

本文主要是介绍libevent之android与鸿蒙编译过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

    最近基于libevent开发了一个端侧的缓存代理库,先是基于macOS编译开发的,基本0问题,后来移植到鸿蒙与android时遇到一些编译链接问题。

    libevent版本如下:

软件版本号libevent-2.1.8

android编译

编译环境

android studio版本ndk编译链版本api级别

Android Studio Flamingo | 2022.2.1 Patch 2
Build #AI-222.4459.24.2221.10121639, built on May 12, 2023
Runtime version: 17.0.6+0-17.0.6b802.4-9586694 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 14.3.1
GC: G1 Young Generation, G1 Old Generation
Memory: 2048M
Cores: 10
Metal Rendering is ON
Registry:
    external.system.auto.import.disabled=true
    ide.text.editor.with.preview.show.floating.toolbar=false
    ide.instant.shutdown=false
    gradle.version.catalogs.dynamic.support=true

Non-Bundled Plugins:
    OpenGL-Plugin (1.0.73)
    Dart (222.4582)
    com.localizely.flutter-intl (1.18.3-2022.2)
    io.flutter (74.0.2)
 

~/Library/Android/sdk/ndk/22.1.717167028

问题现象

ld: error: undefined symbol: arc4random_addrandom
>>> referenced by evutil_rand.c
>>>               evutil_rand.o:(evutil_secure_rng_add_bytes) in archive ./.libs/libevent.a
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [sample/dns-example] Error 1
make: *** [all] Error 2
/Applications/Xcode.app/Contents/Developer/usr/bin/make  install-amCCLD     sample/dns-example
ld: error: undefined symbol: arc4random_addrandom
>>> referenced by evutil_rand.c
>>>               evutil_rand.o:(evutil_secure_rng_add_bytes) in archive ./.libs/libevent.a
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [sample/dns-example] Error 1
make: *** [install] Error 2

解决办法

    找到evutil_rand.c文件,将以下代码注释掉即可:

// void
// evutil_secure_rng_add_bytes(const char *buf, size_t n)
// {
// 	arc4random_addrandom((unsigned char*)buf,
// 	    n>(size_t)INT_MAX ? INT_MAX : (int)n);
// }

    贴出android下编译libevent为arm64和armv7a架构的shell脚本: 

#!/bin/bash#根据实际安装位置修改
export ANDROID_NDK_HOME=/Users/mingo/Library/Android/sdk/ndk/21.1.6352462
export TOOLCHAIN_DIR=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64
export SYSROOT=$TOOLCHAIN_DIR/sysrootexport TARGET_ARCH=aarch64-linux-android
export TOOLCHAIN=$TOOLCHAIN_DIR
export API_LEVEL=21
TARGET=aarch64-linux-android${API_LEVEL}export CLANG="$TOOLCHAIN/bin/aarch64-linux-android$API_LEVEL-clang"
export CLANGXX="$TOOLCHAIN/bin/aarch64-linux-android$API_LEVEL-clang++"
export AR="$TOOLCHAIN/bin/aarch64-linux-android-ar"
export LD="$TOOLCHAIN/bin/aarch64-linux-android-ld"
export RANLIB="$TOOLCHAIN/bin/aarch64-linux-android-ranlib"
export STRIP="$TOOLCHAIN/bin/aarch64-linux-android-strip"#根据实际安装位置修改
OPENSSL_OUTPUT=/Users/mingo/Applications/workspace/opensrc/openssl-android/android
OPENSSL_DIR=${OPENSSL_OUTPUT}/aarch64
PKG_CONFIG_PATH="$OPENSSL_DIR/lib/pkgconfig"CFLAGS="--sysroot=$SYSROOT -I$OPENSSL_DIR/include --target=$TARGET -fPIC -DEVUTIL_DISABLE_ARC4RANDOM"
LDFLAGS="--sysroot=$SYSROOT -L$OPENSSL_DIR/lib -lz -lc"OUTPUT_DIR=$(pwd)/android/$TARGET_ARCH
mkdir -p ${OUTPUT_DIR}function build() {./configure --host=$TARGET_ARCH --prefix=$OUTPUT_DIR \--with-sysroot=${SYSROOT} \--with-openssl=$OPENSSL_DIR \--disable-shared \--disable-arc4random \CC=$CLANG \CXX=$CLANGXX \AR=$AR \RANLIB=$RANLIB \CFLAGS="$CFLAGS" \LDFLAGS="$LDFLAGS"make cleanmake j8make install
}
buildTARGET_ARCH=arm-linux-androideabi
TARGET=arm-linux-android${API_LEVEL}
OUTPUT_DIR=$(pwd)/android/$TARGET_ARCH
mkdir -p ${OUTPUT_DIR}OPENSSL_DIR=${OPENSSL_OUTPUT}/armv7a
PKG_CONFIG_PATH="$OPENSSL_DIR/lib/pkgconfig"CFLAGS="--sysroot=$SYSROOT -I$OPENSSL_DIR/include --target=$TARGET -fPIC -DEVUTIL_DISABLE_ARC4RANDOM"
LDFLAGS="--sysroot=$SYSROOT -L$OPENSSL_DIR/lib -lz"build

openssl编译 

#!/bin/bash#根据实际安装位置修改
export ANDROID_NDK_HOME=/Users/mingo/Library/Android/sdk/ndk/21.1.6352462
export TOOLCHAIN_DIR=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64
export PATH=$TOOLCHAIN_DIR/bin:$PATHexport TARGET_ARCH=aarch64
export API_LEVEL=21  # Android 5.0 (Lollipop)export CC="$TOOLCHAIN_DIR/bin/aarch64-linux-android$API_LEVEL-clang"
export CXX="$TOOLCHAIN_DIR/bin/aarch64-linux-android$API_LEVEL-clang++"
export AR="$TOOLCHAIN_DIR/bin/aarch64-linux-android-ar"
export AS="$TOOLCHAIN_DIR/bin/aarch64-linux-android-as"
export LD="$TOOLCHAIN_DIR/bin/aarch64-linux-android-ld"
export RANLIB="$TOOLCHAIN_DIR/bin/aarch64-linux-android-ranlib"
export STRIP="$TOOLCHAIN_DIR/bin/aarch64-linux-android-strip"function build() {make cleanOUTPUT_DIR=$(pwd)/android/$TARGET_ARCHmkdir -p ${OUTPUT_DIR}#config for android arm64./Configure ${TARGET} -D__ANDROID_API__=${API_LEVEL} no-asm zlib no-shared no-ssl2 no-ssl3 no-comp no-hw no-engine --prefix=${OUTPUT_DIR}make -j8make install
}
TARGET=android-arm64
buildexport TARGET_ARCH=armv7aexport TARGET_HOST=armv7a-linux-androideabi
export CC="$TOOLCHAIN_DIR/bin/${TARGET_HOST}${API_LEVEL}-clang"
export CXX="$TOOLCHAIN_DIR/bin/${TARGET_HOST}${API_LEVEL}-clang++"
export AR="$TOOLCHAIN_DIR/bin/${TARGET_HOST}-ar"
export AS="$TOOLCHAIN_DIR/bin/${TARGET_HOST}-as"
export LD="$TOOLCHAIN_DIR/bin/${TARGET_HOST}-ld"
export RANLIB="$TOOLCHAIN_DIR/bin/${TARGET_HOST}-ranlib"
export STRIP="$TOOLCHAIN_DIR/bin/${TARGET_HOST}-strip"TARGET=android-arm
build

注意

1)在一个app项目里,ndk编译的时候要记得android api级别要一致,就比如本文app的android api级别要求位21,那么在编译libevent和openssl的时候,都要调整为21方可。 

鸿蒙编译

编译环境

DevEco版本编译链版本api级别
DevEco Studio NEXT Developer Beta3
Build #DS-233.14475.28.36.503600
Build Version: 5.0.3.600, built on August 7, 2024
Runtime version: 17.0.10+1-b1087.17 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 14.3.1
GC: G1 Young Generation, G1 Old Generation
Memory: 2048M
Cores: 10
Metal Rendering is ON
Registry:
  idea.plugins.compatible.build=IC-233.14475.28
 
~/Library/OpenHarmony/Sdk/1212

    先是到华为官网下载DevEco IDE开发工具,ID安装好后,再安装鸿蒙编译链,选择api 12的ndk版本进行安装:

下载中心 | 华为开发者联盟-HarmonyOS开发者官网,共建鸿蒙生态

    编译链安装完毕,本文默认安装在以下目录: 

mingo@localhost:~/Library/OpenHarmony/Sdk/12$pwd
/Users/mingo/Library/OpenHarmony/Sdk/12
mingo@localhost:~/Library/OpenHarmony/Sdk/12$tree -L 2
.
├── native
│   ├── NOTICE.txt
│   ├── build
│   ├── build-tools
│   ├── llvm
│   ├── nativeapi_syscap_config.json
│   ├── ndk_system_capability.json
│   ├── oh-uni-package.json
│   └── sysroot
└── toolchains├── NOTICE.txt├── ark_disasm├── configcheck├── diff├── hdc├── hnpcli├── id_defined.json├── idl├── lib├── libusb_shared.dylib├── modulecheck├── oh-uni-package.json├── restool├── syscap_tool└── syscapcheck11 directories, 15 files

编译脚本 

    编译链安装完毕,便可以利用该工具链进行编译了,贴出完整编译脚本: 

#!/bin/bashset -e# 根据实际位置修改
HARMONY_SDK_PATH=/Users/mingo/Library/OpenHarmony/Sdk/12CLANG=$HARMONY_SDK_PATH/native/llvm/bin/clang
CLANGXX=$HARMONY_SDK_PATH/native/llvm/bin/clang++
AR=$HARMONY_SDK_PATH/native/llvm/bin/llvm-ar
RANLIB=$HARMONY_SDK_PATH/native/llvm/bin/llvm-ranlib# compile for aarch64
TARGET_ARCH=aarch64-linux-gnu
TARGET=aarch64-linux-ohos
SYSROOT=$HARMONY_SDK_PATH/native/sysrootZLIB_ROOT_PATH=${HARMONY_SDK_PATH}/native/sysroot/usr
ZLIB_INCLUDE_PATH=${ZLIB_ROOT_PATH}/include
ZLIB_LIB_PATH=${ZLIB_ROOT_PATH}/lib/aarch64-linux-ohos# 根据实际位置修改
OPENSSL_DIR=/Users/mingo/Applications/workspace/opensrc/openssl/hmos/aarch64
PKG_CONFIG_PATH="$OPENSSL_DIR/lib/pkgconfig"
CPPFLAGS="-I$OPENSSL_DIR/include -I${ZLIB_INCLUDE_PATH}"SYSLIB_INCLUDE_DIR=${SYSROOT}/usr/include/aarch64-linux-ohos
echo "syslib=$SYSLIB_INCLUDE_DIR"
CFLAGS="--sysroot=$SYSROOT -I$SYSLIB_INCLUDE_DIR -I$OPENSSL_DIR/include -I$ZLIB_INCLUDE_PATH --target=$TARGET -fPIC"
#CFLAGS="--sysroot=$SYSROOT -I$SYSLIB_INCLUDE_DIR -I$ZLIB_INCLUDE_PATH --target=$TARGET -fPIC"
LDFLAGS="--sysroot=$SYSROOT -L$OPENSSL_DIR/lib -L$ZLIB_LIB_PATH -lz"export CC=$CLANG
export CXX=$CLANGXX
export AR=$AR
export RANLIB=$RANLIB
export CFLAGS=$CFLAGS
export LDFLAGS=$LDFLAGS# compile for libevent-2.1.8-stable
LIBEVENT_SRC_PATH=`pwd`/libevent-2.1.8-stablecd $LIBEVENT_SRC_PATH
PREFIX=${LIBEVENT_SRC_PATH}/ohos/aarch64
mkdir -p ${PREFIX}function build_event() {make cleanmake distclean./configure --host=$TARGET_ARCH --prefix=$PREFIX \--with-sysroot=${SYSLIB_INCLUDE_DIR} \--with-openssl=$OPENSSL_DIR \--with-zlib=$ZLIB_ROOT_PATH \--disable-shared \CC=$CLANG \CXX=$CLANGXX \AR=$AR \RANLIB=$RANLIB \CFLAGS="$CFLAGS" \LDFLAGS="$LDFLAGS"make verbose=1make installcd ..
}build_event

提示:鸿蒙编译链编译libevent的时候,先是下载的api=10的编译链,但在找系统库文件的时候找不到,于是切到api=12级别的编译链,可顺利编译出所需静态库。 

openssl编译

#!/bin/bashexport ANDROID_NDK_HOME=/Users/mingo/Library/Android/sdk/ndk/21.1.6352462
export TOOLCHAIN_DIR=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64
export PATH=$TOOLCHAIN_DIR/bin:$PATHexport TARGET_ARCH=aarch64
export API_LEVEL=21  # Android 5.0 (Lollipop)export CC="$TOOLCHAIN_DIR/bin/aarch64-linux-android$API_LEVEL-clang"
export CXX="$TOOLCHAIN_DIR/bin/aarch64-linux-android$API_LEVEL-clang++"
export AR="$TOOLCHAIN_DIR/bin/aarch64-linux-android-ar"
export AS="$TOOLCHAIN_DIR/bin/aarch64-linux-android-as"
export LD="$TOOLCHAIN_DIR/bin/aarch64-linux-android-ld"
export RANLIB="$TOOLCHAIN_DIR/bin/aarch64-linux-android-ranlib"
export STRIP="$TOOLCHAIN_DIR/bin/aarch64-linux-android-strip"function build() {make cleanOUTPUT_DIR=$(pwd)/android/$TARGET_ARCHmkdir -p ${OUTPUT_DIR}#config for android arm64./Configure ${TARGET} -D__ANDROID_API__=${API_LEVEL} no-asm zlib no-shared no-ssl2 no-ssl3 no-comp no-hw no-engine --prefix=${OUTPUT_DIR}make -j8make install
}
TARGET=android-arm64
buildexport TARGET_ARCH=armv7aexport TARGET_HOST=armv7a-linux-androideabi
export CC="$TOOLCHAIN_DIR/bin/${TARGET_HOST}${API_LEVEL}-clang"
export CXX="$TOOLCHAIN_DIR/bin/${TARGET_HOST}${API_LEVEL}-clang++"
export AR="$TOOLCHAIN_DIR/bin/${TARGET_HOST}-ar"
export AS="$TOOLCHAIN_DIR/bin/${TARGET_HOST}-as"
export LD="$TOOLCHAIN_DIR/bin/${TARGET_HOST}-ld"
export RANLIB="$TOOLCHAIN_DIR/bin/${TARGET_HOST}-ranlib"
export STRIP="$TOOLCHAIN_DIR/bin/${TARGET_HOST}-strip"TARGET=android-arm
build

这篇关于libevent之android与鸿蒙编译过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1097715

相关文章

将图片导入Python的turtle库的详细过程

《将图片导入Python的turtle库的详细过程》在Python编程的世界里,turtle库以其简单易用、图形化交互的特点,深受初学者喜爱,随着项目的复杂度增加,仅仅依靠线条和颜色来绘制图形可能已经... 目录开篇引言正文剖析1. 理解基础:Turtle库的工作原理2. 图片格式与支持3. 实现步骤详解第

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

Linux系统调试之ltrace工具使用与调试过程

《Linux系统调试之ltrace工具使用与调试过程》:本文主要介绍Linux系统调试之ltrace工具使用与调试过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、ltrace 定义与作用二、ltrace 工作原理1. 劫持进程的 PLT/GOT 表2. 重定

Maven 依赖发布与仓库治理的过程解析

《Maven依赖发布与仓库治理的过程解析》:本文主要介绍Maven依赖发布与仓库治理的过程解析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下... 目录Maven 依赖发布与仓库治理引言第一章:distributionManagement配置的工程化实践1

Android 实现一个隐私弹窗功能

《Android实现一个隐私弹窗功能》:本文主要介绍Android实现一个隐私弹窗功能,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 效果图如下:1. 设置同意、退出、点击用户协议、点击隐私协议的函数参数2. 《用户协议》、《隐私政策》设置成可点击的,且颜色要区分出来res/l

Spring三级缓存解决循环依赖的解析过程

《Spring三级缓存解决循环依赖的解析过程》:本文主要介绍Spring三级缓存解决循环依赖的解析过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、循环依赖场景二、三级缓存定义三、解决流程(以ServiceA和ServiceB为例)四、关键机制详解五、设计约

spring IOC的理解之原理和实现过程

《springIOC的理解之原理和实现过程》:本文主要介绍springIOC的理解之原理和实现过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、IoC 核心概念二、核心原理1. 容器架构2. 核心组件3. 工作流程三、关键实现机制1. Bean生命周期2.

Redis实现分布式锁全解析之从原理到实践过程

《Redis实现分布式锁全解析之从原理到实践过程》:本文主要介绍Redis实现分布式锁全解析之从原理到实践过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、背景介绍二、解决方案(一)使用 SETNX 命令(二)设置锁的过期时间(三)解决锁的误删问题(四)Re

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整