移植FreeSwitch到Android 4.4

前期准备

首先板子跑的是android 4.4,编译需要Android NDK,打算以嵌入式linux的方式交叉编译FreeSwitch,并能够后台运行FreeSwitch。

为何是4.4,因为公司的板子是4.4,理论上后续的版本,也是一样的。工具链下了官网的android-ndk-r10e-linux-x86_64.zip,下载比较慢,用迅雷速度还是可以的!

设置Android交叉编译的一些全局参数:

#!/bin/bash

ANDROID_VERSION=19
NDK_PATH=$NDK
HOST=arm-linux-androideabi
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-arm
ANDROID_CFLAGS="-march=armv7-a -mfloat-abi=softfp -fprefetch-loop-arrays --sysroot=${SYSROOT}"
TOOLCHAIN_VERSION=4.9
BUILD_PLATFORM=linux-x86_64
CXX_STL=gnu-libstdc++
TARGET_ARCH=armeabi

TOOLCHAIN=${NDK_PATH}/toolchains/${HOST}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
CXX_STL_PATH=${NDK_PATH}/sources/cxx-stl/${CXX_STL}/${TOOLCHAIN_VERSION}/
CXX_STL_CPPFLAGS="-I${CXX_STL_PATH}/include -I${CXX_STL_PATH}/libs/${TARGET_ARCH}/include"
CXX_STL_LDFLAGS="-L${CXX_STL_PATH}/libs/${TARGET_ARCH}/"

export PKG_CONFIG_PATH="${SYSROOT}/usr/lib/pkgconfig/:${SYSROOT}/usr/local/lib/pkgconfig/"
export CPP=${TOOLCHAIN}/bin/${HOST}-cpp
export AR=${TOOLCHAIN}/bin/${HOST}-ar
export AS=${TOOLCHAIN}/bin/${HOST}-as
export NM=${TOOLCHAIN}/bin/${HOST}-nm
export CC=${TOOLCHAIN}/bin/${HOST}-gcc
export LD=${TOOLCHAIN}/bin/${HOST}-ld
export RANLIB=${TOOLCHAIN}/bin/${HOST}-ranlib
export OBJDUMP=${TOOLCHAIN}/bin/${HOST}-objdump
export STRIP=${TOOLCHAIN}/bin/${HOST}-strip
export CXX=${TOOLCHAIN}/bin/${HOST}-g++

export PATH=${TOOLCHAIN}/bin:$PATH

在编译的终端设置了这些变量后,开始编译。目前编译使用虚拟机centos 7.3.1611,为了保证后续的成功运行,我们使用的版本与centos 7所自带的版本一致。

编译依赖库

FreeSwitch的依赖库较多,因此对应的依赖库,一个个来编译。

libjpeg-turbo

使用libjpeg-turbo-1.5.2版本,进行编译,其中github编译有开启–with-simd,不过实测,开启了会编译不过,所以关闭了选项,编译开关如下:

autoreconf -fi && ./configure --host=${HOST} CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE"  CPPFLAGS="${ANDROID_CFLAGS}"  \
    LDFLAGS="${ANDROID_CFLAGS} -pie" --without-simd --prefix=${SYSROOT}/usr/

需要注意的是,1.2.90版本的–host要配置成arm,否则还不能识别HOST为arm-linux-androideabi,可以正常编译成功。

openssl

使用官方1.0.1e版本,进行编译,编译如下:

CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE -I${SYSROOT}/usr/include "  CPPFLAGS="${ANDROID_CFLAGS} -L${SYSROOT}/usr/lib"  LDFLAGS="${ANDROID_CFLAGS} -pie"\
    ANDROID_DEV="${SYSROOT}/usr" ./Configure android-armv7 --openssldir=${SYSROOT}/usr/ssl/ --prefix=${SYSROOT}/usr/ shared no-ssl2 no-ssl3 no-comp no-hw
CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE -I${SYSROOT}/usr/include "  CPPFLAGS="${ANDROID_CFLAGS} -L${SYSROOT}/usr/lib"  LDFLAGS="${ANDROID_CFLAGS} -pie" \
    ANDROID_DEV="${SYSROOT}/usr" make && make install_sw

pcre

使用官方8.32版本。
autoreconf -fi && CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE -I${SYSROOT}/usr/include"  CPPFLAGS="${ANDROID_CFLAGS} -L${SYSROOT}/usr/lib ${CXX_STL_CPPFLAGS}"  \
    LDFLAGS="${ANDROID_CFLAGS} -pie ${CXX_STL_LDFLAGS}" ./configure --prefix=${SYSROOT}/usr/ --build=x86_64-redhat-linux  \
    --host=arm  --with-sysroot=${SYSROOT} LIBS="-lgnustl_static" --enable-shared

–build=x86_64-redhat-linux –host=arm参数要带上去,–build是因为我虚拟机使用的是centos 7 64bit,而这个版本的host用arm的即可,还不支持android。

ncurses

使用的版本是5.9版本,不过5.9版本需要打上补丁才行:

diff -Nrup ncurses-5.9.orig/form/fty_num.c ncurses-5.9/form/fty_num.c
--- ncurses-5.9.orig/form/fty_num.c	2010-01-23 22:14:36.000000000 +0100
+++ ncurses-5.9/form/fty_num.c	2013-08-30 17:12:04.953720863 +0200
@@ -40,7 +40,7 @@ MODULE_ID("$Id: fty_num.c,v 1.28 2010/01
 #include <locale.h>
 #endif
 
-#if HAVE_LOCALE_H
+#if HAVE_LOCALE_H && !defined(__BIONIC__)
 #define isDecimalPoint(c) ((c) == ((L && L->decimal_point) ? *(L->decimal_point) : '.'))
 #else
 #define isDecimalPoint(c) ((c) == '.')
@@ -96,7 +96,7 @@ Generic_This_Type(void *arg)
 	  argn->low = args->low;
 	  argn->high = args->high;
 
-#if HAVE_LOCALE_H
+#if HAVE_LOCALE_H && !defined(__BIONIC__)
 	  argn->L = localeconv();
 #else
 	  argn->L = NULL;

编译选项如下:

CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE -I${SYSROOT}/usr/include "  CPPFLAGS="${ANDROID_CFLAGS} -L${SYSROOT}/usr/lib"  LDFLAGS="${ANDROID_CFLAGS} -pie"  \
    ./configure --prefix=${SYSROOT}/usr/  --host=${HOST} --without-cxx --without-cxx-binding

libedit

libedit本来是打算要编译的,结果这个库自己也依赖不少库,因此最后就把FS的configure开关中把libedit给去掉了。所以暂时不编译libedit,如果需要编译,libedit也依赖ncurses。

sqlite

sqlite本来也打算跟随centos 7的版本,不过对应版本发布比较早,编译起来比较费尽,所以去sqlite官网下了sqlite-autoconf-3190300版本编译,方便了很多。编译开关如下:

autoreconf -fi && CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE"  CPPFLAGS="${ANDROID_CFLAGS} -L${SYSROOT}/usr/lib"  LDFLAGS="${ANDROID_CFLAGS} -pie"  ./configure --prefix=${SYSROOT}/usr/  \
    --host=${HOST} --with-sysroot=${SYSROOT}

freetype

freetype使用的是与centos7 一致的2.4.11版本。也不需要打补丁之类的。编译开关如下:

./autogen.sh && CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE"  CPPFLAGS="${ANDROID_CFLAGS} -L${SYSROOT}/usr/lib"  LDFLAGS="${ANDROID_CFLAGS} -pie"  ./configure --prefix=${SYSROOT}/usr/  \
    --host=${HOST} --with-sysroot=${SYSROOT}

libpng

libpng使用1.6.30版本,为何不使用centos7所使用的1.5.13版本是因为FS对libpng的1.5.x版本会调用到函数setjmp,而setjmp在目前需要的android 4.4上有些问题,懒得去找问题了,所以换用1.6.30的省事一些。不过目前libpng的1.6.30关闭了neon的支持,可能会影响一些性能。

autoreconf -fi && CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE"  CPPFLAGS="${ANDROID_CFLAGS} -L${SYSROOT}/usr/lib"\
    LDFLAGS="${ANDROID_CFLAGS} -pie"  ./configure --prefix=${SYSROOT}/usr/  --host=${HOST} \
    --with-sysroot=${SYSROOT}  --enable-arm-neon=off

libogg

libogg没有使用centos7所带的1.3.0版本,而是使用1.3.2版本,比较好编译,libogg被speex所依赖。

autoreconf -fi && CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE"  CPPFLAGS="${ANDROID_CFLAGS} -L${SYSROOT}/usr/lib"  LDFLAGS="${ANDROID_CFLAGS} -pie"  ./configure --prefix=${SYSROOT}/usr/  \
    --host=${HOST} --with-sysroot=${SYSROOT}

speexdsp

使用speexdsp-Speex-1.2rc2版本,也是被speex所依赖。这个编译也比较容易。

./autogen.sh && CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE"  CPPFLAGS="${ANDROID_CFLAGS} -L${SYSROOT}/usr/lib"  LDFLAGS="${ANDROID_CFLAGS} -pie"  ./configure --prefix=${SYSROOT}/usr/ \
    --host=${HOST} --with-sysroot=${SYSROOT}

要先执行autogen.sh生成configure文件。

speex

使用的是1.2.0版本,编译选项也不复杂,能够成功编译:

autoreconf -fi && CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE"  CPPFLAGS="${ANDROID_CFLAGS} -L${SYSROOT}/usr/lib"  LDFLAGS="${ANDROID_CFLAGS} -pie"  ./configure --prefix=${SYSROOT}/usr/  \
    --host=${HOST} --with-sysroot=${SYSROOT}

libuuid

FS需要依赖libuuid,在centos上的并非是单独的libuuid,而是被包含在util-linux-2.23.2中,我们去SF上下载libuuid-1.0.3,编译开关大同小异,可以编译通过。

autoreconf -fi && CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE"  CPPFLAGS="${ANDROID_CFLAGS} -L${SYSROOT}/usr/lib"  LDFLAGS="${ANDROID_CFLAGS} -pie"  ./configure --prefix=${SYSROOT}/usr/  \
    --host=${HOST} --with-sysroot=${SYSROOT} --with-pic

libsndfile

libsndfile使用1.0.26版本,比较好编译,去其github下载对应版本就行。

autoreconf -fi && CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE -gstabs "  CPPFLAGS="${ANDROID_CFLAGS} -L${SYSROOT}/usr/lib"  \
    LDFLAGS="${ANDROID_CFLAGS} -pie" CXXFLAGS="${CXXFLAGS} -gstabs -fno-exceptions --sysroot=${SYSROOT} -I${SYSROOT}/usr/include ${CXX_STL_CPPFLAGS}"  \
    ./configure --prefix=${SYSROOT}/usr/  --host=${HOST} --with-sysroot=${SYSROOT}

由于有使用到C++,因此需要设置C++的一些相关参数。

ldns

使用1.7.0版本

autoreconf -fi && ./configure --host=${HOST} CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE"  CPPFLAGS="${ANDROID_CFLAGS}"  LDFLAGS="${ANDROID_CFLAGS} -pie" \
    --prefix=${SYSROOT}/usr/ --with-sysroot=${SYSROOT} --with-ssl=${SYSROOT}/usr/ --disable-dane-verify

opus

使用最新的1.2.1版本

autoreconf -fi && ./configure --host=${HOST} CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE"  CPPFLAGS="${ANDROID_CFLAGS}"  LDFLAGS="${ANDROID_CFLAGS} -pie" \
    --prefix=${SYSROOT}/usr/ --with-sysroot=${SYSROOT}

由于lua也是需要libreadline的,而目前我们不编译libreadline,所以要把modules.conf

#languages/mod_lua

lua模块注释掉。

如果以上的库都编译成功后,那么,接下来,则可以编译FS了。

编译FS

FS我是用的是1.6.11版本,需要打上一些补丁才行,目前还不支持android。而由于上文中,我们并没有编译libedit,因此这里的话,我们需要–disable-core-libedit-support这个开关来关闭对libedit的支持。libvpx需要单独编译,因为目前FS工程中的参数是写死的。

libvpx

对于1.6.11这个版本的FS对于libvpx参数的设定,并不能成功编译出android版本,因此可以单独去libs/libvpx进行编译:

CFLAGS="${ANDROID_CFLAGS} -O3 -fPIE"  CPPFLAGS="${ANDROID_CFLAGS} -L${SYSROOT}/usr/lib"  LDFLAGS="${ANDROID_CFLAGS} -pie ${CXX_STL_LDFLAGS}" CPPLDFLAGS="${ANDROID_CFLAGS} ${CXX_STL_LDFLAGS}"  \
    ./configure --prefix=${SYSROOT}/usr/  --target=armv7-android-gcc --enable-pic --disable-docs --disable-examples --disable-install-bins --disable-install-srcs  --cpu=cortex-a8 --sdk-path=$NDK

由于libvpx编译成安卓版本,会依赖cpu-features,因此需要单独编译下cpu-features:

$CC ${ANDROID_CFLAGS}  -fPIE -I${SYSROOT}/usr/inclue -c $NDK_PATH/sources/android/cpufeatures/cpu-features.c -o cpu-features.o
$AR crs libcpu-features.a cpu-features.o

之后FS需要多链接-lcpu-features

autoreconf -fi && ./rebootstrap.sh && PKG_CONFIG_PATH=$PKG_CONFIG_PATH ./configure --with-sysroot=${SYSROOT} --host=${HOST} --prefix=${SYSROOT}/usr/ --disable-core-libedit-support \
    CC="$CC" LD="$LD" NM="$NM" AR="$AR" CPP="$CPP" CXX="$CXX" CFLAGS="${ANDROID_CFLAGS}  -fPIE -I${SYSROOT}/usr/inclue ${CXX_STL_CPPFLAGS}"  CPPFLAGS="${ANDROID_CFLAGS} ${CXX_STL_CPPFLAGS}" \
    LDFLAGS="${ANDROID_CFLAGS} -pie -Wl,-rpath-link=${SYSROOT}/usr/lib -L${SYSROOT}/usr/lib -L${SYSROOT}/usr/lib ${CXX_STL_LDFLAGS}" CPPLDFLAGS="${ANDROID_CFLAGS} ${CXX_STL_LDFLAGS}" \
    CXXFLAGS="${ANDROID_CFLAGS} ${CXX_STL_CPPFLAGS}" CXXLDFLAGS="${ANDROID_CFLAGS} ${CXX_STL_LDFLAGS}" \
    --with-pkgconfigdir="$PKG_CONFIG_PATH" LIBS="-lgnustl_static -lsupc++ -lcpu-features"

后续我会将这些可以编译的版本,以及补丁上传到github上,如果有兴趣的,可以去支持下,先整理这些。后续还需要调试很多东西才行。github地址在:https://github.com/elkpi/freeswitch-android

出现的一些问题

编译出现的错误,还是不少的,FS需要改动一些源码。其中可能会经常遇到的是:crtend_so.o以及crtbegin_so.o未能被找到并编译,这两个其实NDK中已经有提供了已经编译好的文件了。解决办法是:

CFLAGS+=--sysroot=${SYSROOT}
CPPFLAGS+=--sysroot=${SYSROOT}
CXXFLAGS+=--sysroot=${SYSROOT}

也就是所有的编译参数中,都要指定–sysroot参数,这样NDK提供的工具链就可以自己找到crtend_so.o以及crtbegin_so.o。至于其余的问题,我也忘记记录了。

 

 

 

 

转载请注明: 转载自elkPi.com

本文链接地址: 移植FreeSwitch到Android 4.4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Scroll to top