2019-10-21
AS和cmake笔记
android的cpu架构
- android查看cpu架构(
termux
)
cat /proc/cpuinfo |
cmake在AS中的使用
不要把mk
和cmake
两种方法混淆
输出控制(message
)
(TODO)如果想直接看到打印信息,使用
WARNING
以上的级别进行打印
message(WARNING "fuck")
- 在
Build
->Build Output
->CMake warnings
查看 - 在
Build
->Build Output
->Toggle View
查看
- 在
Android
- 版本信息
Android Studio
版本为3.5Build-Tools
版本为28.0.3
- 需要使用
SDK Manager
安装- ndk
- cmake
只使用java
模块
3.x
-3.4.7
-3.x
版本
File
->New
->Import Module
->选择opencv文件夹下的sdk/java
文件夹,此时Android Studio
会自动加载Module name
- 将
opencv
模块的AndroidManifest.xml
中<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" />
删除 File
->Project Structure
->Dependencies
->选择app
->添加Module Dependency
->选择opencv- 将opencv文件夹下的
sdk/native/libs
下自己手机cpu对应的架构文件夹复制到app/libs
下 - 将opencv模块的
build.gradle
的complieSdkVersion
,buildToolVersion
,minSdkVersion
,targetSdkVersion
改成和app
的build.gradle
一样 - 在
app
的build.gradle
的android
节点下添加然后点击sourceSets {
main {
jni.srcDirs = []
jniLibs.srcDirs = ['libs']
}
}sync now
- 在使用opencv前进行初始化
static {
if (!OpenCVLoader.initDebug()) {
...
}
}
常见错误
Caused by: CvException [org.opencv.core.CvException: OpenCV(4.1.1) /build/master_pack-android/opencv/modules/java/generator/src/cpp/utils.cpp:101: error: (-215:Assertion failed)
在Mat
与Bitmap
互转的时候长宽设置不对
只使用native
模块
3.x
-3.4.7
-3.x
版本
方法一
CMakeLists.txt
编写- include头文件目录
- 加载libopencv动态库(
libopencv_world
或libopencv_java3
),命名为opencv_lib
- 将
opencv_lib
加载至目标文件
set(opencv_dir /home/lynx/fuck_mount/opencv/build_dir/4_1_0_shared/OpenCV-android-sdk) |
- 修改app的
build.gradle
- 在
android
节点下插入,否则会报错找不到libopencv_world.so
或libopencv_java3.so
- 在
sourceSets { |
方法二
CMakeLists.txt
- 设置OpenCV查找的目录
- 查找OpenCV
- include头文件目录
- 将OpenCV的库添加至目标文件
set(sdk_dir /home/lynx/fuck_mount/opencv/build_dir/4_1_0_shared) |
- 如果不设置
OpenCV_DIR
将无法查找OpenCV
包
- 修改app的
build.gradle
sourceSets { |
- 此外,务必将
minSdkVersion
调至21以上,否则将会只有v8a
架构才能成功编译 - 在app的
build.gradle
中:minSdkVersion
->ANDROID_PLATFORM
- 在
ndk
的android.toolchain.cmake
中:ANDROID_PLATFORM
->ANDROID_PLATFORM_LEVEL
->ANDROID_NATIVE_API_LEVEL
- 如果不设置
minSdkVersion
,由于以上的确定关系,ANDROID_NATIVE_API_LEVEL
会被设置为16,find_package
会失败
4.x
-4.1.0
-4.x
版本
方法一
同3.x
版本的方法一
方法二
同3.x
版本的方法二
常见问题
java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found
(4.x
版本)
(不确定的解决方法)在app的gradle中修改
externalNativeBuild { |
不要使用gnustl_shared
或gnustl_static
,已经过时
java.lang.UnsatisfiedLinkError: dlopen failed: library "libopencv_java3.so" not found
(或libopencv_java4.so
)
这是由于忘记了上面的第2步.Android Studio默认的jni
路径为app/src/main/jniLibs
,除了在CMakeLists.txt
中导入opencv的库以外还需要二选一
- 将对应版本opencv的库(
libs/
下一级的各个${ANDROID_ABI}
文件夹)移动到jniLibs
下 - 在
build.gradle
中修改默认jni
路径(见上面第2步)
- 各种
undefined reference to *
(3.x
版本)
如std::ios_base::Init::Init()
等
TODO
- 各类
AndroidBitmap
的问题(3.x
版本)
undefined reference to `AndroidBitmap_getInfo' |
在CMakeLists.txt
增加
target_link_libraries( |
参考:CSDN,这是一个很小的库,展示一个稳定的,基于C语言的接口,使本机代码安全地访问Java对象的像素缓冲区的位图
source code(使用完整代码)
3.x
-3.x
版本(未成功,需要eclipse)
4.x
-4.1.0
-4.x
版本
环境变量
JAVA_HOME
export JAVA_HOME=/home/lynx/fuck_mount/Android_Studio/jre # 使用Android Studio的JDK位置
ANDROID_SDK
(非必须)export ANDROID_SDK=/home/lynx/fuck_mount/Android_SDK
ANDROID_NDK
(非必须)export ANDROID_NDK=/home/lynx/fuck_mount/Android_SDK/ndk/{版本}
调整结构
- 修改toolchain:android ndk的
ndk/build/cmake/android.toolchain.cmake
(约112行)elseif(ANDROID_TOOLCHAIN_NAME MATCHES "-[0-9].[0-9]$")
set(ANDROID_TOOLCHAIN clang) # 将gcc改成clang
endif() - android stl,在源代码的
/platforms/android/build_sdk.py
(约113行)(非必须)self.cmake_vars = dict(
ANDROID_STL="c++_static", # change `gnustl_static` to `c++_static` or `c++_shared`
ANDROID_ABI=self.name,
ANDROID_PLATFORM_ID=platform_id,
) - 在
Android Studio
的android sdk文件夹下,创建软连接ln -s build-tools/{版本} tools
,否则无法编译安卓模块
- 修改toolchain:android ndk的
修改
cmake
参数(2选1,推荐world)(修改根CMakeLists.txt
)- java
OPENCV_ENABLE_NONFREE
:改为ON
BUILD_SHARED_LIBS
:不动或者改为OFF
,与生成java库冲突BUILD_ANDROID_PROJECTS
:不动或者改为ON
BUILD_FAT_JAVA_LIB
:不动或者改为ON
,保证生成libopencv_java4.so
BUILD_JAVA
:不动或者改为ON
- 对
/samples/android/CMakeLists.txt
中除了ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-declarations)
那一行,其他全部注释掉,否则android sdk会在编译sample时报错
- world
OPENCV_ENABLE_NONFREE
:改为ON
BUILD_SHARED_LIBS
:改为ON
BUILD_ANDROID_PROJECTS
:不动或者改为ON
BUILD_FAT_JAVA_LIB
:改为OFF
,生成libopencv_world.so
BUILD_JAVA
:不动或者改为ON
- 对
/samples/android/CMakeLists.txt
中除了ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-declarations)
那一行,其他全部注释掉,否则android sdk会在编译sample时报错
- java
执行
platforms/android/build_sdk.py
,完成编译
./build_sdk.py --ndk_path {ndk路径} --sdk_path {android sdk路径} --extra_modules_path {path_to_contrib/modules} {目标位置} {opencv源码位置} |
如果没有设置则默认为环境变量
sdk-path
:Android Studio的SDK目录ndk-path
:Android Studio的SDK目录下ndk/{ndk版本号文件}
- 后续关于
CMakeLists.txt
(android项目内的)和build.gradle
的修改同native
方法
常见错误
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.stitch-sPWgBONIqUrdX9XLB1OY6w==/base.apk"],nativeLibraryDirectories=[/data/app/com.example.stitch-sPWgBONIqUrdX9XLB1OY6w==/lib/arm64, /data/app/com.example.stitch-sPWgBONIqUrdX9XLB1OY6w==/base.apk!/lib/arm64-v8a, /system/lib64, /product/lib64]]] couldn't find "libnative-lib.so"
缺少相应ABI的so
库(目前计时在gradle里加入abiFilters
也没有用),上述报错是因为没有编译全ABI.ABI
配置:opencv-4.x/platforms/android/ndk-18-api-level-21.config.py
- 没装
cmake
Executing: ['ninja', '--version'] |
Android Studio需要在SDK Manager里面预先安装CMake
,否则编译的时候会找不到ninja
等程序
没有
libopencv_java4.so
BUILD_FAT_JAVA_LIB
和BUILD_ANDROID_PROJECTS
要设置ON
(或默认)- 记得修改android sdk tools文件结构
- 不能同时编译动态库
编译错误
Regex: 'command line option .* is valid for .* but not for C\+\+' |
TODO,可能是编译器的问题或cmake参数设置错误
- android project报错
A problem occurred configuring project ':face-detection'. |
把samples/android/CMakeLists.txt
对应代码注释掉
- ndk报错
CMake Error at /home/lynx/fuck_mount/Android_SDK/ndk/20.1.5948944/build/cmake/android.toolchain.cmake:169 (message): |
需要将ndk
的build/cmake/android.toolchain.cmake
中set(ANDROID_TOOLCHAIN gcc)
改为clang
- ninja报错
CMake Error: CMake was unable to find a build program corresponding to "Ninja". CMAKE_MAKE_PROGRAM is not set. You probably need to select a different build tool. |
将ndk的bin
目录(包含ninja
等程序)添加至$PATH
- ccache未安装(
3.x
版本,TODO:不确定是否为必须)
用apt安装ccache
即可
- ld报错(
3.x
版本)
cannot open crtbegin_dynamic.o: 没有那个文件或目录 |
TODO修改gcc
参数(但很大程度上是由于cmake参数配置错误)
- 添加
-nostdlib
- 修改
--sysroot
参数
- clang++报错
error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory |
使用apt安装libtinfo5
- 编译错误
error: use of undeclared identifier 'vcvt_f16_f32' |
多种可能
- 换
ndk
opencv_contrib
的路径设置错误
libopencv_java3.so
没有生成(3.x
版本)
TODO,很大程度上是由于cmake参数配置错误
- cmake报错
Android SDK: Can't build Android projects as requested by |
4.x
:android sdk build tool版本过低3.x
:需要sdk整合ant(ide为eclipse)
- java报错
opencv init failed |
检查gradle
的lib
路径是否正确加载
freetype
/harfbuzz
报错
卸载系统中的freetype
和harfbuzz
在opencv_contrib/modules/freetype/CMakeLists.txt
中修改
if(PKG_CONFIG_FOUND) |
注释掉搜索freetype
和harfbuzz
的那两句
额外说明
4.x
版本
- 不需要额外安装的软件:
jdk
,ninja-build
,ndk
,直接使用android studio的即可 - 成功编译的版本:
ndk
:20.1.5948944
sdk tools
:28.0.3
cmake
:3.13.4
- 失败的版本:
ndk
:21.0.6113669
(报错undefined referrence to '__write_chk'
)sdk tools
:25.0.3
(不能configure android project)
3.x
版本 目前还没能成功编译android project
3.x
成功编译的版本:- 无
- 失败的版本:
ndk
:20.1.5948944
(报错undefined referrence to '__vsnprintf_chk'
)
使用JavaCV
4.x
版本
不同导入方法,
import
的class位置可能不同
opencv
部分功能的初始化
Loader.load(opencv_java.class);// 不能直接放在class开头 |
使用远程导入
app
的build.gradle
示例(最外节点)
ext { |
作为lib
导入
根据手机具体的cpu架构进行导入
app
的build.gradle
dependencies { |
将文件(视具体情况)
javacpp.jar
javacv.jar
openblas.jar
openblas-android-arm64.jar
opencv.jar
opencv-android-arm64.jar
复制到app/libs/
文件夹里
常见错误
- cpu架构错误/缺少(需添加
-android-arm
之类的库)
2019-10-27 16:01:32.439 29256-29322/? E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1 |
- 没有对
opencv
初始化
2019-10-27 16:00:43.930 28933-28933/? E/AndroidRuntime: FATAL EXCEPTION: main |
- 缺少
openblas
的相关jar
库
2019-10-27 15:59:23.158 28618-28618/? E/AndroidRuntime: FATAL EXCEPTION: main |
混用java
+native
模块
4.x
native
(或source code)+3.x
java
加载
native
模块File
->New
->Import Module
->选择opencv文件夹下的sdk/java
文件夹,自己定义模块的名字修改模块的gradle文件(TODO)
// 将原来的application改成library |
- 修改app的gradle文件,加载两者的lib,缺一不可
sourceSets { |
- 修改app的gradle文件,添加java模块依赖
|
Linux
OpenCV
source code 3.x
(3.4.7
)
gui安装
和4.x
一样
常见错误
fatal error: Eigen/Core: 没有那个文件或目录``#include <Eigen/Core>
修改
WITH_EIGEN=OFF
(或)
- 先保证安装
eigen
:sudo apt install libeigen3-dev
- 添加
EIGEN_INCLUDE_PATH=/usr/include/eigen3
(视具体情况)
- 先保证安装
ippicv_linux_20141027.tgz
下载失败CMake Error at 3rdparty/ippicv/downloader.cmake:71 (file):
file DOWNLOAD HASH mismatch
for file: [/home/lynx/fuck_mount/opencv_3_0_0/opencv/3rdparty/ippicv/downloads/linux-8b449a536a2157bcad08a2b9f266828b/ippicv_linux_20141027.tgz]
expected hash: [8b449a536a2157bcad08a2b9f266828b]
actual hash: [5c4f36bf7b2421d52289f0297ba1406f]
status: [28;"Timeout was reached"]
TODO
ippicv_2019_lnx_intel64_general_20180723.tgz
下载超时IPPICV: Download: ippicv_2019_lnx_intel64_general_20180723.tgz
CMake Warning at cmake/OpenCVDownload.cmake:193 (message):
IPPICV: Download failed: 28;"Timeout was reached"在
opencv/opencv_3rdparty
的ippicv
对应分支中下载对应的tgz
将
tgz
放入/home/lynx/Downloads/
修改opencv的source code:
vi /3rdparty/ippicv/ippicv.cmake
,将ippicv
的https
地址改为file:/home/lynx/Downloads/
重新
cmake-gui
OpenCV
source code 4.x
(4.1.0
)
依赖包
sudo apt install libgtk2.0-dev pkg-config # libgtk-3-dev |
一定要安装,否则会报错
- 缺少
gtk
terminate called after throwing an instance of 'cv::Exception' |
命令行安装(TODO)
cmake
cd {生成makefile的位置} |
make
cd {生成makefile的位置} |
make install
make install {安装的位置} |
gui安装
- 安装
cmake-gui
sudo apt install cmake-gui |
- 启动
cmake-gui
cd {build二进制文件的目录} |
Configure
->Unix Makefiles
:Use default native compilers
->finish
狂点
Configure
直到没有红色区域赋值
变量名 | 赋值 |
---|---|
BUILD_EXAMPLES |
|
CMAKE_BUILD_TYPE |
Release |
CMAKE_INSTALL_PREFIX |
{自己定的cmake_install 路径} |
OPENCV_ENABLE_NONFREE |
勾选 |
OPENCV_EXTRA_MODULES_PATH |
{opencv-contrib source code}/modules |
OPENCV_GENERATE_PKGCONFIG |
勾选 |
狂点
Configure
Generate
,等到Generating done
在build路径
make
sudo make -j4 # 具体看有多少cpu |
配置
opencv4.pc
(2选1)- 修改
PKG_CONFIG_PATH
:增加{你cmake_install的路径}/lib/pkgconfig
(opencv4.pc
所在的路径) - (TODO,没试过)复制
opencv4.pc
到/usr/lib/pkgconfig
- 修改
配置库路径,(新建)
/etc/ld.so.conf.d/opencv.conf
{你cmake_install路径}/lib/ # 自己的lib路径 |
sudo ldconfig |
- 编译测试
如果是
opencv.pc
将opencv4
改成opencv
pkg-config --modversion opencv4 |
常见问题
- 在其他项目中用
CMake
导入OpenCV
模块:之后find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})cmake
出现By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH ...
:
这是由于没有设置环境变量OpenCV_DIR
,设置为OpenCV
编译后的目录下含有OpenCVConfig.cmake
的对应路径
VIDIOC_REQBUFS: Inappropriate ioctl for device
: 缺少ffmpeg
TODO: 需要在安装ffmpeg(以源代码的方式安装, 不要使用apt)之后重新编译OpenCV, ffmpeg安装