Quantcast
Channel: Sam的技术Blog
Viewing all articles
Browse latest Browse all 158

OpenCV4Android编译详解

$
0
0
作者: Sam(甄峰)  sam_code@hotmail.com

0. 背景简介: 
之前为Android平台分别编译过OpenCV2.0,  OpenCV2.4.20 OpenCV3.0等版本。并记录下来:
http://blog.sina.com.cn/s/blog_602f87700102wwvb.html
http://blog.sina.com.cn/s/blog_602f87700102vewh.html
http://blog.sina.com.cn/s/blog_602f87700102vdnw.html
http://blog.sina.com.cn/s/blog_602f87700101de4o.html
也为Linux编译过OpenCV各个版本: 
http://blog.sina.com.cn/s/blog_602f87700102wuv7.html

但当前遇到一些新要求: 
1. 使用clang而非g++编译。
2. 使用stlport而非gnustl.
考虑到NDK R18将不再支持GCC. 也强力推荐libc++. 所以这个研究也是必要的。

此次编译,
1. 将使用NDK R15C, NDK R10.  NDK R17b 等版本NDK。 但必须使用clang.
2. 分别编译OpenCV3.1.  OpenCV3.4.


1. OpenCV3.1编译脚本研究:
1.0. 目录结构和脚本入口
在OpenCV3.1 目录下,包含platforms/scripts. 这个目录存放着一系列编译脚本。我们为ARM平台的Android编译OpenCV。则使用cmake_android_arm.sh 这个脚本。
#cd platforms
# sh scripts/cmake_android_arm.sh

#!/bin/sh
cd `dirname $0`/..

mkdir -p build_android_arm
cd build_android_arm

cmake -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON -DCMAKE_TOOLCHAIN_FILE=../android/android.toolchain.cmake $@ ../..

讲解如下: 
cd 'dirname $0'/..
进入scripts的上一级目录。即platforms.

mkdir -p build_android_arm
cd build_android_arm
创建build_android_arm目录。并进入。

cmake -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON -DCMAKE_TOOLCHAIN_FILE=../android/android.toolchain.cmake $@ ../..
使用cmake编译。 使用的Makefile为../..下的CMakeLists.txt。
cmake $@ ../.. 
即把参数以列表形式传递进来。


1.1. CMAKE_TOOLCHAIN_FILE分析
1.1.1:
android/android.toolchain.cmake
它是ANdroid  CMake toolchain file. 并明确指出使用NDK 如-r10d.(这也许解释了为何使用R15C时,无法指定clang为编译器)

文件中讲解了如何对编译器相关的选项进行设置。
使用如下方法:
A:设置到环境变量中。
export
=
例如: 
export ANDOIRD_NDK=/opt/android-ndk-r10d
这个方法不一定起效。但Sam没看出原因。

B: 写入scripts/cmake_android_arm.sh
利用它传递进去。 
-D
=
例如,把如下内容加入cmake_android_arm.sh: 
-DANDROID_ABI=armeabi-v7a


1.1.2:设置选项
指定NDK目录
ANDROID_NDK=/opt/android-ndk-r10d

指定指令集:
ANDROID_ABI=armeabi-v7a
可选项有很多,armeabi, armeabi-v7a,  armeabi-v7a-hard with NEON,  armeabi-v7a with NEON, x86, mips, arm64-v8a. 等等。

指定Native  API Level:
ANDROID_NATIVE_API_LEVEL=android-24

指定ToolChain:
ANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.9

支持以下设置(脚本对R10C 以后的NDK处理的不够好,会导致Clang找不到):
#        * aarch64-linux-android-4.9
#        * aarch64-linux-android-clang3.4
#        * aarch64-linux-android-clang3.5
#        * arm-linux-androideabi-4.6
#        * arm-linux-androideabi-4.8
#        * arm-linux-androideabi-4.9 (default)
#        * arm-linux-androideabi-clang3.4
#        * arm-linux-androideabi-clang3.5
#        * mips64el-linux-android-4.9
#        * mips64el-linux-android-clang3.4
#        * mips64el-linux-android-clang3.5
#        * mipsel-linux-android-4.6
#        * mipsel-linux-android-4.8
#        * mipsel-linux-android-4.9
#        * mipsel-linux-android-clang3.4
#        * mipsel-linux-android-clang3.5
#        * x86-4.6
#        * x86-4.8
#        * x86-4.9
#        * x86-clang3.4
#        * x86-clang3.5
#        * x86_64-4.9
#        * x86_64-clang3.4
#        * x86_64-clang3.5

指定C++库:
ANDROID_STL=gnustl_shared

#      Possible values are:
#        none           -> Do not configure the runtime.
#        system         -> Use the default minimal system C++ runtime library.
#                          Implies -fno-rtti -fno-exceptions.
#                          Is not available for standalone toolchain.
#        system_re      -> Use the default minimal system C++ runtime library.
#                          Implies -frtti -fexceptions.
#                          Is not available for standalone toolchain.
#        gabi++_static  -> Use the GAbi++ runtime as a static library.
#                          Implies -frtti -fno-exceptions.
#                          Available for NDK r7 and newer.
#                          Is not available for standalone toolchain.
#        gabi++_shared  -> Use the GAbi++ runtime as a shared library.
#                          Implies -frtti -fno-exceptions.
#                          Available for NDK r7 and newer.
#                          Is not available for standalone toolchain.
#        stlport_static -> Use the STLport runtime as a static library.
#                          Implies -fno-rtti -fno-exceptions for NDK before r7.
#                          Implies -frtti -fno-exceptions for NDK r7 and newer.
#                          Is not available for standalone toolchain.
#        stlport_shared -> Use the STLport runtime as a shared library.
#                          Implies -fno-rtti -fno-exceptions for NDK before r7.
#                          Implies -frtti -fno-exceptions for NDK r7 and newer.
#                          Is not available for standalone toolchain.
#        gnustl_static  -> Use the GNU STL as a static library.
#                          Implies -frtti -fexceptions.
#        gnustl_shared  -> Use the GNU STL as a shared library.
#                          Implies -frtti -fno-exceptions.
#                          Available for NDK r7b and newer.
#                          Silently degrades to gnustl_static if not available.


1.2: cmake/OpenCVFindLibsPerf.cmake:
这个文件用来查找需要的库和头文件目录。
例如: 
platforms/scripts/cmake_android_arm.sh 中添加:
-DHAVE_EIGEN=1
此时 调用: sh scripts/cmake_android_arm.sh 
关于Eigen的结果有点异常:
--   Other third-party libraries:
--     Use Eigen:                   YES (ver ..)
没有得到版本号,则一定没有找到对应头文件等。查看CMakeLists.txt。以下几项内容缺失。
${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION}

则修改如下:
if(WITH_EIGEN)
  find_path(EIGEN_INCLUDE_PATH "Eigen/Core"
            PATHS /usr/local /opt /usr  ENV ProgramFiles ENV ProgramW6432
            PATH_SUFFIXES include/eigen3  /home/sam/work/current/Reaearch/OpenCV3.1/opencv-3.1.0/3rdparty/eigen
            DOC "The path to Eigen3/Eigen2 headers"
            CMAKE_FIND_ROOT_PATH_BOTH)

1.3:cmake/OpenCVDetectCXXCompiler.cmake
这里设置编译器FLAGS。
例如:
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  set(CMAKE_COMPILER_IS_GNUCXX 1)
  set(CMAKE_COMPILER_IS_CLANGCXX 1)
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
  set(CMAKE_COMPILER_IS_GNUCC 1)
  set(CMAKE_COMPILER_IS_CLANGCC 1)
endif()
设置了Clang的Flags。

1.4:cmake/OpenCVCompilerOptions.cmake
设置编译选项。
例如: 如果想增加clang编译器编译时的编译选项。可以做如下动作:
if(CMAKE_COMPILER_IS_CLANGCXX)
add_extra_compiler_option(-std=c++11)
endif()
则把 -std=c++11加入了编译想选。










#!/bin/sh
cd `dirname $0`/..

mkdir -p build_android_arm
cd build_android_arm

cmake -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON -DHAVE_EIGEN=1 -DWITH_FFMPEG=ON -DHAVE_CAMV4L2=ON -DBUILD_TBB=ON -DWITH_TBB=ON -DBUILD_EXAMPLES=1  -DANDROID_STL=stlport_shared -DCMAKE_TOOLCHAIN_FILE=../android/android.toolchain.cmake $@ ../..

doctutorials/introduction/android_binary_package/android_ocl_intro.markdown.



 

Viewing all articles
Browse latest Browse all 158

Trending Articles