博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android跨平台编译 —— libevent
阅读量:7115 次
发布时间:2019-06-28

本文共 6950 字,大约阅读时间需要 23 分钟。

hot3.png

此文大量引用参考 

前言

    前言都在 

    PS:有一些基础知识介绍,还是挺重要的。

    

准备工作

    编译环境 mac os x

    ndk版本 ndk 16rb

    libevent版本 2.1.8

    编译工具 cmake

    假设我们已经在android studio上安装了ndk和cmake。

    首先需要下载libevent ,这里有个问题,如果直接从官网上下载tar包,解压之后是没有CMakeLists.txt文件的,所以无法使用cmake进行编译。所以我们需要从github上直接下载,地址

去clone下来,然后checkout到 release-2.1.8-stable 这个tag上。

    环境已经准备就绪。

    

编译

步骤1

   首先打开根目录下的CMakeLists.txt文件,有几处改动

diff --git a/CMakeLists.txt b/CMakeLists.txtindex b4a34f3d..c32721d1 100644--- a/CMakeLists.txt+++ b/CMakeLists.txt@@ -105,7 +105,7 @@ option(EVENT__BUILD_SHARED_LIBRARIES     "Define if libevent should be built with shared libraries instead of archives" OFF)  option(EVENT__DISABLE_DEBUG_MODE-    "Define if libevent should build without support for a debug mode" OFF)+    "Define if libevent should build without support for a debug mode" ON)  option(EVENT__ENABLE_VERBOSE_DEBUG     "Enables verbose debugging" OFF)@@ -117,7 +117,7 @@ option(EVENT__DISABLE_THREAD_SUPPORT     "Define if libevent should not be compiled with thread support" OFF)  option(EVENT__DISABLE_OPENSSL-    "Define if libevent should build without support for OpenSSL encrpytion" OFF)+    "Define if libevent should build without support for OpenSSL encrpytion" ON)  option(EVENT__DISABLE_BENCHMARK     "Defines if libevent should build without the benchmark exectuables" OFF)@@ -328,8 +328,8 @@ CHECK_FUNCTION_EXISTS_EX(strtoll EVENT__HAVE_STRTOLL) CHECK_FUNCTION_EXISTS_EX(vasprintf EVENT__HAVE_VASPRINTF) CHECK_FUNCTION_EXISTS_EX(sysctl EVENT__HAVE_SYSCTL) CHECK_FUNCTION_EXISTS_EX(accept4 EVENT__HAVE_ACCEPT4)-CHECK_FUNCTION_EXISTS_EX(arc4random EVENT__HAVE_ARC4RANDOM)-CHECK_FUNCTION_EXISTS_EX(arc4random_buf EVENT__HAVE_ARC4RANDOM_BUF)+#CHECK_FUNCTION_EXISTS_EX(arc4random EVENT__HAVE_ARC4RANDOM)+#CHECK_FUNCTION_EXISTS_EX(arc4random_buf EVENT__HAVE_ARC4RANDOM_BUF) CHECK_FUNCTION_EXISTS_EX(epoll_create1 EVENT__HAVE_EPOLL_CREATE1) CHECK_FUNCTION_EXISTS_EX(getegid EVENT__HAVE_GETEGID) CHECK_FUNCTION_EXISTS_EX(geteuid EVENT__HAVE_GETEUID)@@ -492,7 +492,7 @@ CHECK_TYPE_SIZE("void *" EVENT__SIZEOF_VOID_P) #CHECK_FILE_OFFSET_BITS() #set(EVENT___FILE_OFFSET_BITS _FILE_OFFSET_BITS) -include(CheckWaitpidSupportWNOWAIT)+#include(CheckWaitpidSupportWNOWAIT)  # Verify kqueue works with pipes. if (EVENT__HAVE_KQUEUE)@@ -846,17 +846,17 @@ if (EVENT__BUILD_SHARED_LIBRARIES)                                       ${CMAKE_THREAD_LIBS_INIT}                                       ${LIB_PLATFORM}) -  set_target_properties(event-        PROPERTIES SOVERSION-            ${EVENT_ABI_LIBVERSION})+#  set_target_properties(event+#        PROPERTIES SOVERSION+#            ${EVENT_ABI_LIBVERSION}) -  set_target_properties(event_core-        PROPERTIES SOVERSION-            ${EVENT_ABI_LIBVERSION})+#  set_target_properties(event_core+#        PROPERTIES SOVERSION+#            ${EVENT_ABI_LIBVERSION}) -  set_target_properties(event_extra-        PROPERTIES SOVERSION-            ${EVENT_ABI_LIBVERSION})+#  set_target_properties(event_extra+#        PROPERTIES SOVERSION+#            ${EVENT_ABI_LIBVERSION})  else (EVENT__BUILD_SHARED_LIBRARIES)     set(EVENT_EXTRA_FOR_TEST event_extra)

    首先我关闭了debug模式和openssl的支持(关于需要的设置因人而异,用户可以自己选择设置。)

    另外我关闭了arc4random和arc4random_buf的检测(关于这部分我会在下文说明)

    去掉了CheckWaitpidSupportWNOWAIT

    另外去掉了编译出来的库文件的版本后缀。(比如最后库文件是libevent.a 而不是libevent.a.2.1.8)

步骤2

    在根目录下创建android.sh,内容如下

NDK_PATH=/Users/yxwang/Library/Android/sdk/ndk-bundle/ #换成你自己的ndk pathSHELL_FOLDER=$(cd "$(dirname "$0")";pwd)BUILD_PATH=$SHELL_FOLDER/android_build/echo $BUILD_PATHif [ -x "$BUILD_PATH" ]; then		rm -rf $BUILD_PATHfimkdir $BUILD_PATHmkdir $BUILD_PATH/outfor abi in armeabi armeabi-v7a arm64-v8a x86 x86_64do  #cmake        MakePath=./cmake/build-$abi  echo $MakePath	if [ -x "$MakePath" ]; then		rm -rf $MakePath	fi	mkdir $MakePath		OUTPUT_PATH=$BUILD_PATH/out/$abi/	echo $OUTPUT_PATH	if [ -x "$OUTPUT_PATH" ]; then		rm -rf $OUTPUT_PATH	fi	mkdir $OUTPUT_PATH		cd $MakePath	    # DCMAKE_INSTALL_PREFIX 最后install的路径 这里是 android_build/$abi    # DCMAKE_TOOLCHAIN_FILE 这个的路劲在android studio中创建一个带有ndk的项目,编译一下,然后    # 在.externalNativeBuild/cmake/***/cmake_build_command.txt中找到    # stl 我们使用c++_static	cmake -DCMAKE_TOOLCHAIN_FILE=$NDK_PATH/build/cmake/android.toolchain.cmake \    -DANDROID_NDK=$NDK_PATH                      \    -DCMAKE_BUILD_TYPE=Release                     \    -DANDROID_ABI=$abi          \    -DANDROID_NATIVE_API_LEVEL=16                  \    -DANDROID_STL=c++_static \    -DCMAKE_CXX_FLAGS=-frtti -fexceptions --std=c++1z \    -DCMAKE_INSTALL_PREFIX=$OUTPUT_PATH \    ../..		make -j4	make install		cd ../..	done

     

步骤三

    运行上面的脚本 (chmod +x android.sh添加执行权限才能运行。)

    发现在编译过程中会报出如下错误

^In file included from /Users/yxwang/workspace/gittest/libevent/evutil_rand.c:134:/Users/yxwang/workspace/gittest/libevent/./arc4random.c:498:1: error: static declaration of 'arc4random_buf' follows non-static      declarationarc4random_buf(void *buf_, size_t n)^/Users/yxwang/Library/Android/sdk/ndk-bundle/sysroot/usr/include/stdlib.h:124:6: note: previous declaration is herevoid arc4random_buf(void* __buf, size_t __n);     ^1 error generated.

    什么意思呢,就是我arc4random_buf重复定义了,并且一处是static一处不是,这就出现了冲突,导致编译失败。我们分别来看下两处代码

// arc4random.cARC4RANDOM_EXPORT voidarc4random_buf(void *buf_, size_t n){	.....}// $NDK_PATH/sysroot/usr/include/stdlib.hvoid arc4random_buf(void* __buf, size_t __n);

    其中ARC4RANDOM_EXPORT在evutil_rand.c中有定义

#define ARC4RANDOM_EXPORT static

    查看evutil_rand.c文件,有一个非常关键的宏 EVENT__HAVE_ARC4RANDOM 表示运行的系统是否自带ARC4RANDOM功能。

    如果没有自带,那么ARC4RANDOM_EXPORT 才会被定义为static。这里他被定义为static了,也就是我们告诉了编译器我们没有自带ARC4RANDOM。我们是如何实现的?就是通过

    -CHECK_FUNCTION_EXISTS_EX(arc4random EVENT__HAVE_ARC4RANDOM)

    -CHECK_FUNCTION_EXISTS_EX(arc4random_buf EVENT__HAVE_ARC4RANDOM_BUF)
    +#CHECK_FUNCTION_EXISTS_EX(arc4random EVENT__HAVE_ARC4RANDOM)
    +#CHECK_FUNCTION_EXISTS_EX(arc4random_buf EVENT__HAVE_ARC4RANDOM_BUF)

    关闭了arc4random检测。

    如果我们开启这个检测,EVENT__HAVE_ARC4RANDOM就会被设置为 1 。

    我们可以通过查看编译过程中自动生成的 event-config.h 文件查看这个宏是否有被设置。

    (如果使用上面提供的脚本可以在cmake/build-xxx/include/event2文件夹中找到自动生成的文件)

    所以干嘛多次一举嘛!干脆开启这个检测好了,尝试编译,竟然通过了!!但是,有个并不算好的消息,一旦你打开检测,cmake检测到arc4random存在,arc4random_buf存在,就把宏打开了,表示你已经实现了arc4random相关的代码了,我就不去定义实现了。

    然后在运行使用的时候,比如调用到了evutil_rand.c中的这个方法

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

    进一步会调用arc4random_addrandom,编译器就会报错,表示arc4random_addrandom这个函数不存在!

    虽然在libevent中这个函数式定义了但是它是现在arc4random.c文件中,只有EVENT__HAVE_ARC4RANDOM未设置的时候才会被#include到evutil_rand.c中。

    所以理论上来说arc4random_addrandom一旦你设置了EVENT__HAVE_ARC4RANDOM,就意味着你需要去实现arc4random_addrandom方法,但是在ndk中,arc4random是被裁剪了的,他只有如下三个方法

                                uint32_t arc4random(void);

                                uint32_t arc4random_uniform(uint32_t __upper_bound);
                                void arc4random_buf(void* __buf, size_t __n);

    我们可以在stdlib.h中看到声明。

    所以为了解决这个问题,做法是手动修改stdlib.h文件,将以上三个定义注释掉。(编译通过之后重新打开,保证我们没有修改ndk,防止以后使用错误)其中stdlib.h文件在ndk-bundle/sysroot/usr/include中。

 

编译完成

    再次运行android.sh之后编译完成,输出文件在android-build文件夹中,各个abi都已经编译出来。

转载于:https://my.oschina.net/zzxzzg/blog/1623523

你可能感兴趣的文章
SQL Server 2008连接字符串写法大全
查看>>
序列模型(4)----门控循环单元(GRU)
查看>>
Python画三维图-----插值平滑数据
查看>>
librbd 分析
查看>>
sql里的in对应linq的写法 及 IQueryable转化为Dictionary
查看>>
LWIP
查看>>
针对上一篇文章中的代码,想出的重构方案(python实现)
查看>>
HTML+JS版本的俄罗斯方块
查看>>
awk的模块化方案,在这公司苦逼很久以后想到的
查看>>
如何用Django从零开始搭建一个网站(0)
查看>>
Spring boot 整合 Mybatis
查看>>
C++对象的数据成员
查看>>
hashMap_使用
查看>>
iniparser解析文件说明。
查看>>
Apache2.4 多端口虚拟目录配置
查看>>
Node.js入门
查看>>
[百度之星]资格赛:IP聚合
查看>>
POJ 1328 Radar Installation 贪心
查看>>
python常用问题收集
查看>>
奇怪的sqlconnection.open错误
查看>>