ubuntu16.04 编译 openblas mxnet for Android
编译版本
-
openblas-0.3.5
-
mxnet-master
-
ndk-r18
生成工具链
#将ndk目录加入环境变量
export NDK_BUNDLE_DIR=${HOME}/Android/sdk/ndk-bundle
#将toolchain目录加入环境变量
export MY_ANDROID_TOOLCHAIN=${HOME}/Android/sdk/my-android-toolchain
#生成独立工具链
$NDK_BUNDLE_DIR/build/tools/make_standalone_toolchain.py \
--arch arm --api 16 --install-dir ${MY_ANDROID_TOOLCHAIN}
#将独立工具链工具加入环境变量(clang和arm-linux-androideabi-*)
export PATH=${MY_ANDROID_TOOLCHAIN}/bin:$PATH
#配置要使用的工具
export target_host=arm-linux-androideabi
export AR=$target_host-ar
export AS=$target_host-clang
export CC=$target_host-clang
export CXX=$target_host-clang++
export LD=$target_host-ld
export STRIP=$target_host-strip
编译Openblas
#设置LDFLAGS,以便链接器找到合适的libgcc
export LDFLAGS="-L${MY_ANDROID_TOOLCHAIN}/lib/gcc/arm-linux-androideabi/4.9.x"
#设置clang交叉编译标志
export CLANG_FLAGS="-target arm-linux-androideabi -marm -mfpu=vfp -mfloat-abi=softfp --sysroot ${MY_ANDROID_TOOLCHAIN}/sysroot -gcc-toolchain ${MY_ANDROID_TOOLCHAIN}/arm-linux-androideabi"
#进入OpenBLAS源码目录
cd OpenBLAS-0.3.5/
#编译ARMV7环境静态库
make TARGET=ARMV7 ONLY_CBLAS=1 AR=$AR CC="clang ${CLANG_FLAGS}" HOSTCC=gcc ARM_SOFTFP_ABI=1 NO_SHARED=1 -j4
#安装静态库
make NO_SHARED=1 PREFIX=./android-openblas-arm install
编译完android-openblas-arm目录下会有头文件与静态库文件
注意:
这里使用make编译时加了NO_SHARED=1
参数表示不编译动态库,因为不加的话编译时会发生如下错误:
../libopenblas_armv7p-r0.3.5.so: error: undefined reference to 'stderr'
编译脚本在编译完动态库后会拿动态库与linktest.c
文件进行编译,在link时会报错上面的错误,这个问题我解决不掉,因此只能不编译动态库只编译静态库,有解决这个问题的希望能告知我如何解决
已解决,使用最新的方法来编译OpenBLAS:https://blog.csdn.net/lj402159806/article/details/91436075
编译mxnet
git clone时需要使用--recursive
参数把引用的一些第三方库都clone下来
git clone --recursive https://github.com/apache/incubator-mxnet.git
然后根据这个github项目内的Makefile
amalgamation.py
mxnet_predict0.cc
文件修改mxnet源码中amalgamation目录内相应文件
Makefile文件中OPENBLAS_ROOT路径需要更改为openblas make install后生成的绝对路径,如下:
ifndef OPENBLAS_ROOT
export OPENBLAS_ROOT=${HOME}/Android/OpenBLAS-0.3.5/android-openblas-arm/
endif
最后进入amalgamation内执行make ANDROID=1
编译即可
编译完成后会在amalgamation目录内生成jni_libmxnet_predict.so
libmxnet_predict.a
文件,libmxnet_predict.so
文件在../lib
目录下
注意:
libmxnet_predict.so文件放在android cmake项目中如果报java.lang.UnsatisfiedLinkError: dlopen failed: library “libXXX.so” not found
错误的话需要在CMakeLists.txt里加入一行:set_property(TARGET lib_mxnet PROPERTY IMPORTED_NO_SONAME 1)
示例如下:
add_library(lib_mxnet SHARED IMPORTED)
set_property(TARGET lib_mxnet PROPERTY IMPORTED_NO_SONAME 1)
set_target_properties(lib_mxnet PROPERTIES
IMPORTED_LOCATION ${jniLibs}/libmxnet_predict.so)
因为使用上面方式编译出来的动态库文件是没有SONAME
的(可以使用readelf -d filename.so
命令来查看)
参考
https://developer.android.com/ndk/guides/standalone_toolchain
https://github.com/xianyi/OpenBLAS/wiki/How-to-build-OpenBLAS-for-Android
https://github.com/apache/incubator-mxnet/tree/master/amalgamation