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.