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-am
  CCLD     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

# 根据实际ndk编译链位置修改
export ANDROID_NDK_HOME=/Users/mingo/Library/Android/sdk/ndk/22.1.7171670
export TOOLCHAIN_DIR=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64
export SYSROOT=$TOOLCHAIN_DIR/sysroot

export TARGET_ARCH=aarch64-linux-android
export TOOLCHAIN=$TOOLCHAIN_DIR
export API_LEVEL=28
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位置修改
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"

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 clean
    make j8
    make install
}
build

TARGET_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:$PATH

export 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 clean
    OUTPUT_DIR=$(pwd)/android/$TARGET_ARCH
    mkdir -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 -j8
    make install
}
TARGET=android-arm64
build

export TARGET_ARCH=armv7a

export 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

鸿蒙编译

编译环境

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
    └── syscapcheck

11 directories, 15 files

编译脚本 

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

#!/bin/bash

set -e

# 根据实际位置修改
HARMONY_SDK_PATH=/Users/mingo/Library/OpenHarmony/Sdk/12

CLANG=$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/sysroot

ZLIB_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-stable

cd $LIBEVENT_SRC_PATH
PREFIX=${LIBEVENT_SRC_PATH}/ohos/aarch64
mkdir -p ${PREFIX}

function build_event() {
    make clean
    make 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=1
    make install
    cd ..
}

build_event

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

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:$PATH

export 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 clean
    OUTPUT_DIR=$(pwd)/android/$TARGET_ARCH
    mkdir -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 -j8
    make install
}
TARGET=android-arm64
build

export TARGET_ARCH=armv7a

export 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker部署postgresSQL 并做持久化

先安装docker,安装docker 方法自行寻找方法 然后安装pgsql 拉取镜像 docker pull registry.cn-hangzhou.aliyuncs.com/qiluo-images/postgres:latest运行容器 docker run -it --name postgres --privileged --restart always -e POSTGRES_PASSWORDYo5WYypu0mCCh…

input[type=checkbox]勾选框自定义样式

效果图&#xff1a; <template> <input class"rule-checkbox" type"checkbox" checked v-model"isChecked" /> </template><script setup lang"ts"> import { ref } from vue; const isChecked ref(); </…

Python3:多行文本内容转换为标准的cURL请求参数值

背景 在最近的工作中&#xff0c;经常需要处理一些接口请求的参数&#xff0c;参数来源形式很多&#xff0c;可能是Excel、知识库文档等&#xff0c;有些数据形式比较复杂&#xff0c;比如多行或者包含很多不同的字符&#xff0c;示例如下&#xff1a; **客服质检分析指引** …

性价比运动耳机有哪些?五大性价比运动耳机推荐!

作为一名资深的数码爱好者&#xff0c;我一直对各种新型耳机产品保持着浓厚的兴趣。最近&#xff0c;我因为很多运动爱好者都在询问什么耳机是比较适合运动的时候使用的&#xff0c;看了市面上的产品&#xff0c;开放式耳机无疑是一个不错的选择&#xff0c;它因为采用人体工学…

vue3+ts+vant4 列表下拉刷新+分页加载

效果图 主要代码&#xff1a; <van-pull-refreshv-model"refreshing"refresh"handleRefresh"pulling-text"下拉释放刷新"loosing-text"下拉释放刷新"loading-text"加载中"><van-listv-model:loading"loading…

WPS回应“崩了”:提供15天会员补偿,另有新羊毛,你还不来薅?

近期&#xff0c;“WPS崩了”这一话题在时隔两个月后&#xff0c;再次因多名用户反馈软件使用问题而登上微博热搜。 WPS官方微博随后发布消息称&#xff0c;经过工程师的紧急修复&#xff0c;WPS服务已经恢复正常。 为了补偿用户&#xff0c;在8月22日0点至24点期间&#xff…

【软件测试】软件测试岗位会越来越少吗?

我的整体意见是测试岗位不会变少&#xff0c;反而相对于其他岗位会变的更重要一些。 首先纠正一个非常非常错误的观念。测试和测试开发是两个岗位&#xff1f;No&#xff0c;不是的。测试开发是属于测试的。 测试开发只不过是使用类似于开发的技术和能力&#xff0c;来达到测…

CAPL如何实现在网络节点中添加路由Entry

其实不只是CANoe的网络节点,所有设备的应用程序如果要通过Socket套接字发送报文,在网络层都需要根据路由表里配置的路由条目选择发送路径。这个路由条目可以是静态配置,也可以是自动添加。 如果CANoe的网络节点添加一个网络接口,配置IP地址和子网掩码: 说明此网络节点在1…

C++ 设计模式——策略模式

策略模式 策略模式主要组成部分例一&#xff1a;逐步重构并引入策略模式第一步&#xff1a;初始实现第二步&#xff1a;提取共性并实现策略接口第三步&#xff1a;实现具体策略类第四步&#xff1a;实现上下文类策略模式 UML 图策略模式的 UML 图解析 例二&#xff1a;逐步重构…

Java Web —— 第七天(Mybatis案例 员工管理2)

新增员工 EmpController类 PostMappingpublic Result save(RequestBody Emp emp){log.info("新增员工操作,emp:{}",emp);empService.save(emp);return Result.success();} EmpServiceImpl实现类 //新增员工Overridepublic void save(Emp emp) {//补充基础属性 创…

台球助教在线预约小程序源码开发:打造便捷高效的台球学习新体验

在当今快节奏的生活中&#xff0c;台球作为一项集休闲、竞技与社交于一体的运动&#xff0c;受到了越来越多人的喜爱。然而&#xff0c;对于初学者而言&#xff0c;想要快速提升技能&#xff0c;往往需要专业的指导和陪练。传统的台球教练预约方式往往存在信息不对称、预约流程…

【Qt笔记】Qt界面显示时间

目录 一、前言 二、基本概念 三、代码实现 1. 获取本地时间&#xff0c;并将其转换成自己想要的格式 2.创建一个QLabel控件用于显示时间字符串 3.创建QTimer定时器更新时间 四、优化 1. 格式优化 1.1 初始化 1.2 获取星期 1.3 更改格式 1.4 定时器超时函数 1.5 …

多商户多套部署需修改注意事项

同一台服务器上部署多个多商户项目&#xff0c;需要修改和调整的地方等。 一、修改代码中的端口号&#xff0c;需要两个项目不能使用同一个端口号&#xff0c;例如&#xff1a;A项目用&#xff1a;8324&#xff0c;B项目用&#xff1a;8325&#xff1b; 二、修改反向代理&…

LCP 633 平方数之和 [leetcode - 8]

最近是在研究双指针啊&#xff0c;leetcode刷的题都是这方面的。都记录在最近的文章里&#xff0c;大家有兴趣可以去我主页看看 LCP633 平方数之和 给定一个非负整数 c &#xff0c;你要判断是否存在两个整数 a 和 b&#xff0c;使得 a2 b2 c 。 示例 1&#xff1a; 输入&…

Modbus 数据帧解析

Modbus 是一种通信协议&#xff0c;广泛应用于工业自动化系统中&#xff0c;用于连接电子设备。它是一种基于主从结构的通信协议&#xff0c;其中主设备可以与多个从设备通信。数据通过一系列的帧进行传输&#xff0c;每一帧包含多个字段&#xff0c;每个字段都有特定的功能。 …

HTML 列表和容器元素——WEB开发系列10

HTML 提供了多种方式来组织和展示内容&#xff0c;其中包括无序列表、有序列表、分区元素 ​​<div>​​ 和内联元素 ​​<span>​​、以及如何使用 ​​<div>​​​ 进行布局和表格布局。 一、HTML 列表 1. 无序列表 (​​<ul>​​) 无序列表用于展…

【Win开发环境搭建】Redis与可视化工具详细安装与配置过程

&#x1f3af;导读&#xff1a;本文档提供了Redis的简介、安装指南、配置教程及常见操作方法。包括了安装包的选择与配置环境变量的过程&#xff0c;详细说明了如何通过修改配置文件来设置密码和端口等内容。同时&#xff0c;文档还介绍了如何使用命令行工具连接Redis&#xff…

科研软件 | Diamond 4.6 安装教程

软件介绍 Diamond一个化学专业软件。它是一款在原子水平实现晶体结构可视化的软件&#xff0c;包括分子和聚合物扩展、多面体、搜索结构数据、自动和批量创建结构图片等功能&#xff0c;支持晶体结构着色和渲染以及批注。 软件下载 https://pan.quark.cn/s/37214b5bec7c 软…

05、Redis实战:优惠券秒杀、优化异步下单

6、秒杀优化 6.1 秒杀优化-异步秒杀思路 我们先来回顾一下下单流程当用户发起请求&#xff0c;此时会先请求Nginx&#xff0c;Nginx反向代理到Tomcat&#xff0c;而Tomcat中的程序&#xff0c;会进行串行操作&#xff0c;分为如下几个步骤 查询优惠券判断秒杀库存是否足够查询…

音视频相关知识

H.264编码格式 音频 PCM就是要把声音从模拟信号转换成数字信号的一种技术&#xff0c;他的原理简单地说就是利用一个固定的频率对模拟信号进行采样。 pcm是无损音频音频文件格式 每秒15帧 一秒钟300kb 单位&#xff1a;像素