鉴于为了演示搭建环境时遇到的坑和解决方法,本文写的非常长。
这篇文章是去年写完的,踩坑太多了,没舍得分享,今天还是拿出来帮帮大家。
提升native代码执行效率的方法主要有算法优化,比如for循环展开;neon汇编优化,可以显著提升cpu的效率;另外就是将native代码运行在GPU侧,因为cpu上面跑的任务太多,主线程经常被其他APP抢占,而使用GPU的APP不是很多,所以可以将任务跑在GPU上,OpenCL对GPU硬件有要求,有的GPU支持OpenCL,有的则不支持。华为,荣耀很多手机都支持OpenCL。
另外,本人今天发现opencv的SDK中也有OpenCL的头文件。
但是目前网上几乎没有详细介绍android 引入OpenCL的文章,搭建环境比较艰难,现在写一篇博客记录下。
注意:本人的环境为:荣耀9X手机+Android Studio Artic Fox + Gradle 7.0.2 + JDK11 + Android API 30
如果使用Android Studio Artic Fox创建Android API 28的工程可能会报错,这里有篇文章可以解决问题:Android studio报错Could not find method dependencyResolutionManagement() for arguments的解决方法
本片文章的源代码为:Android OpenCL Demo
本人的源代码放在别的品牌的手机上可能运行奔溃,我在小米平板4上试过,全部报错信息为以下:
(如果有朋友知道报错的原因和解决办法,可以加我的qq:3063886427,或者为我发送邮件3063886427@qq.com ,在此表示感谢)
2021-12-17 15:41:14.392 2293-2545/? W/PushService: 2021-12-17 15:41:14,392 - [WARN::PushService] - [Thread:81] Service called on timer
2021-12-17 19:40:10.108 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libcommon_1_0.so" unused DT entry: type 0x6fffe001 arg 0xc
2021-12-17 19:40:10.108 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libcommon_1_0.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.108 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libhidlbase.so" unused DT entry: type 0x6fffe000 arg 0x27648
2021-12-17 19:36:29.631 3756-10709/? W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:333)
2021-12-17 19:40:10.108 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libhidltransport.so" unused DT entry: type 0x6fffe000 arg 0x3bc
2021-12-17 19:36:29.695 767-4321/? D/ACDB-LOADER: ACDB -> send_audvoltable
at com.miui.activityutil.y.f(SourceFile:315)
2021-12-17 19:40:10.108 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libhwbinder.so" unused DT entry: type 0x6fffe001 arg 0xc
2021-12-17 19:40:10.108 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libhwbinder.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.108 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libutils.so" unused DT entry: type 0x6fffe000 arg 0x84a4
2021-12-17 19:40:10.108 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libutils.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libcutils.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:36:38.287 1513-1532/? D/CompatibilityInfo: applicationScale - 1.0
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe001 arg 0x170
2021-12-17 19:36:38.745 2399-2997/? D/ScreenElementRoot: resume
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libhwbinder.so" unused DT entry: type 0x6fffe000 arg 0x3b8
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libhwbinder.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libvndksupport.so" unused DT entry: type 0x6fffe000 arg 0x524
2021-12-17 19:36:29.393 765-765/? D/QSEECOMAPI: QSEECom_dealloc_memory
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbase.so" unused DT entry: type 0x6fffe000 arg 0x52b8
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbase.so" unused DT entry: type 0x6fffe001 arg 0x10
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbase.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libcutils.so" unused DT entry: type 0x6fffe000 arg 0x3154
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libcutils.so" unused DT entry: type 0x6fffe001 arg 0x78
2021-12-17 19:36:29.630 3756-10709/? W/System.err: at com.miui.cloudservice.stat.StatHelper.recordCountEvent(StatHelper.java:91)
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libcutils.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libutils.so" unused DT entry: type 0x6fffe000 arg 0x84a4
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libutils.so" unused DT entry: type 0x6fffe001 arg 0x30
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbinderthreadstate.so" unused DT entry: type 0x6fffe000 arg 0xc8c
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbinderthreadstate.so" unused DT entry: type 0x6fffe001 arg 0xc
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbinderthreadstate.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe000 arg 0x2b428
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe001 arg 0x170
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe000 arg 0x2b428
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe001 arg 0x170
2021-12-17 19:36:51.730 10951-10951/? D/[DynamicFeature] LoadCompactDynamicFeature: [compact] load: invoked. BuildConfig.IS_QRUN_COMPACT: false AppSetting.isQRunCompact(): false
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libcutils.so" unused DT entry: type 0x6fffe000 arg 0x3154
Remote Branch : quic/gfx-adreno.lnx.1.0.r33-rel
Remote Branch : NONE
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libcutils.so" unused DT entry: type 0x6fffe001 arg 0x78
Reconstruct Branch : NOTHING
2021-12-17 19:36:38.819 1513-1513/? V/MediaRouter: Selecting route: RouteInfo{ name=平板电脑, description=null, status=null, category=RouteCategory{ name=系统 types=ROUTE_TYPE_LIVE_AUDIO ROUTE_TYPE_LIVE_VIDEO groupable=false }, supportedTypes=ROUTE_TYPE_LIVE_AUDIO ROUTE_TYPE_LIVE_VIDEO , presentationDisplay=null }
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libprocessgroup.so" unused DT entry: type 0x6fffe000 arg 0xd528
2021-12-17 19:40:10.109 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libprocessgroup.so" unused DT entry: type 0x6fffe001 arg 0x28
2021-12-17 19:36:52.837 4509-4509/? W/System.err: at java.lang.Integer.parseInt(Integer.java:570)
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libprocessgroup.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libvndksupport.so" unused DT entry: type 0x6fffe001 arg 0xc
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libvndksupport.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbase.so" unused DT entry: type 0x6fffe000 arg 0x52b8
2021-12-17 19:36:47.096 2399-2399/? D/EventBus: No subscribers registered for event class com.miui.home.launcher.common.messages.DragMessage
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbase.so" unused DT entry: type 0x6fffe001 arg 0x10
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbase.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe000 arg 0x2b428
2021-12-17 19:36:53.756 11059-11090/? W/ResourceType: No package identifier when getting name for resource number 0x00000000
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe001 arg 0x170
2021-12-17 19:36:53.970 4509-4509/? W/System.err: at android.os.Looper.loop(Looper.java:164)
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe000 arg 0x2b428
2021-12-17 19:36:54.240 4509-4509/? W/System.err: at android.app.Activity.performPause(Activity.java:7232)
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe001 arg 0x170
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe000 arg 0x2b428
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbase.so" unused DT entry: type 0x6fffe000 arg 0x52b8
2021-12-17 19:36:49.956 2417-2720/? W/WakelockManagerService: uid: 10078 is unblock state
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbase.so" unused DT entry: type 0x6fffe001 arg 0x10
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbase.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libcgrouprc.so" unused DT entry: type 0x6fffe001 arg 0xc
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe000 arg 0x2b428
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe001 arg 0x170
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbase.so" unused DT entry: type 0x6fffe000 arg 0x52b8
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbase.so" unused DT entry: type 0x6fffe001 arg 0x10
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libbase.so" unused DT entry: type 0x6fffe003 arg 0x4
2021-12-17 19:36:57.085 2399-2399/? W/System.err: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4206)
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe000 arg 0x2b428
2021-12-17 19:40:10.110 11354-11354/com.example.myopencldemo W/linker: "/data/app/com.example.myopencldemo-thr6ZrdE9jAl_txHTpLSAw==/lib/arm/libc++.so" unused DT entry: type 0x6fffe001 arg 0x170
2021-12-17 19:40:10.000 11354-11354/? I/zygote: Late-enabling -Xcheck:jni
2021-12-17 19:40:10.077 11354-11354/com.example.myopencldemo W/ResourceType: No package identifier when getting name for resource number 0x00000000
2021-12-17 19:40:10.000 11354-11354/? I/zygote: Late-enabling -Xcheck:jni
2021-12-17 19:40:10.077 11354-11354/com.example.myopencldemo W/ResourceType: No package identifier when getting name for resource number 0x00000000
相信本文对你搭建其他品牌手机的opencl环境有帮助
1.新建native工程
创建后运行一下看成不成功
2.在cpp目录下面创建include文件夹,然后在include文件夹下面创建CL文件夹
3.将OpenCL的头文件复制到CL文件夹下
注意不要将windows版本或者其他电脑版本的OpenCL头文件拷贝过来,必须是手机版本的头文件,我使用beyond compare工具对比发现二者的内容不一样。
4.在CMakeList.txt中添加
include_directories(include)
5.在cpp目录下创建libs文件夹,然后在libs文件夹下面创建armeabi-v7a文件夹
6.将libOpenCL.so库复制到armeabi-v7a文件夹中
6.1 首先要在你的手机里面找到libOpenCL.so这个库,然后把它从手机里面拷贝到电脑上
如果没有在/system/vendor/lib/这个路径下面找到libOpenCL.so这个库,说明可能你的GPU不支持OpenCL
6.2把adb pull出来的libOpenCL.so复制到armeabi-v7a目录下
7.为libOpenCL.so配置CMakelist.txt
add_library(
OpenCL
SHARED
IMPORTED)
set_target_properties(OpenCL PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libOpenCL.so)
target_link_libraries(
myopencldemo
OpenCL
${log-lib})
注意:只有在target_link_libraries引入OpenCL,才能将libOpenCL.so打包进apk中
8.配置app目录下的build.gradle
externalNativeBuild {
cmake {
abiFilters 'armeabi-v7a'
}
}
ndk{
abiFilters 'armeabi-v7a'
}
9.在native-lib.cpp中使用OpenCL
//引入头文件
#include <android/log.h>
#include <android/native_window_jni.h>
#include <CL/cl.h>
#include <CL/cl_platform.h>
#define LOGD(...) __android_log_print(ANDROID_LOG_INFO,"David",__VA_ARGS__)
//引入代码
LOGD("=============================================\n");
/*全局变量*/
cl_platform_id *platforms;//查询后获得的平台列表,存放所有平台的ID
cl_uint num_platforms;//当前可查询的平台的数量
/*第一个JNI,这是查询你的平台数量。*/
jint buffer;//创建一个buffer用以缓存平台数量,并传递;
clGetPlatformIDs(0, NULL, &num_platforms);
//当第二个参数为NULL时,函数将会查询当前可用平台的数量,并保存在第三个参数;
platforms = new cl_platform_id[num_platforms];//查询后获得的平台列表,存放所有平台的ID
//platforms = new cl_platform_id[num_platforms];
clGetPlatformIDs(num_platforms ,platforms ,NULL);
//获取平台数量后可以查询平台,将查询到的平台ID保存在第二个列表参数中
buffer = num_platforms;
LOGD("平台数:%d\n",buffer);
LOGD("平台ID:%d\n",platforms);
LOGD("=============================================\n");
点击运行
发生报错
dlopen failed: library "libcutils.so" not found
原因是libOpenCL.so依赖libcutils.so,我们需要将libcutils.so也拷贝到armeabi-v7a目录下,并在CMakelists.txt中配置。
这里我们进入到了配置OpenCL的难点
实际上libOpenCL.so不只是依赖libcutils.so,还依赖很多其他的库。
可以使用objdump来查看libOpenCL.so依赖哪些库
将libOpenCL.so拷贝到虚拟机下,使用objdump来查看libOpenCL.so依赖哪些库
注意:你的打印可能和我这里的不一样
10.这里,我们需要使用adb把本手机 /system/lib/ 路径下的这些被libOpenCL.so依赖的库都拷贝出来,然后放到armeabi-v7a目录下,并配置CMakelists.txt
cmake_minimum_required(VERSION 3.10.2)
project("myopencldemo")
include_directories(include)
add_library(
OpenCL
SHARED
IMPORTED)
set_target_properties(OpenCL PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libOpenCL.so)
add_library(
base
SHARED
IMPORTED)
set_target_properties(base PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libbase.so)
add_library(
c++
SHARED
IMPORTED)
set_target_properties(c++ PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libc++.so)
add_library(
c
SHARED
IMPORTED)
set_target_properties(c PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libc.so)
add_library(
cutils
SHARED
IMPORTED)
set_target_properties(cutils PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libcutils.so)
add_library(
dl
SHARED
IMPORTED)
set_target_properties(dl PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libdl.so)
add_library(
log
SHARED
IMPORTED)
set_target_properties(log PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/liblog.so)
add_library(
m
SHARED
IMPORTED)
set_target_properties(m PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libm.so)
add_library(
utils
SHARED
IMPORTED)
set_target_properties(utils PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libutils.so)
target_link_libraries(
myopencldemo
utils
m
log
dl
cutils
c
c++
base
OpenCL
${log-lib})
sync完后,点击运行,发现再次报错
dlopen failed: library "libprocessgroup.so" not found
这里,你可能会问,我们不是已经把libOpenCL.so依赖的库都添加进来了吗?为什么这里报错libprocessgroup.so找不到?而且,之前使用objdump打印的依赖库里面并没有libprocessgroup.so。
对于,这个问题,是这样的,我们使用objdump打印的依赖库只是libOpenCL.so直接依赖的库。实际上libOpenCL.so直接依赖的这些库还依赖别的库。
比如:我们打印libutils.so的依赖库
hg@ubuntu:~/tmp$ objdump -x libutils.so | grep NEEDED
NEEDED libcutils.so
NEEDED liblog.so
NEEDED libprocessgroup.so
NEEDED libvndksupport.so
NEEDED libc++.so
NEEDED libc.so
NEEDED libm.so
NEEDED libdl.so
这里就会发现, libutils.so依赖libprocessgroup.so
所以,我们不光要将libOpenCL.so这个库直接依赖的库从手机里面拷贝到armeabi-v7a目录下,也要将这些直接被依赖的库所依赖的库也从手机里面拷贝到armeabi-v7a目录下。
这里,打印下libOpenCL.so直接依赖的库有以下:
libcutils.so
liblog.so
libutils.so
libbase.so
libc++.so
libc.so
libm.so
libdl.so
上面这些库除了互相依赖,还依赖以下这些库:
ld-android.so
libdl_android.so
libvndksupport.so
libprocessgroup.so
libcgrouprc.so
到了这里,聪明的同学可能会想到,要是这些库还有依赖的库,怎么办?没错,我们还需要把上面这些库依赖的库找到。但是实际上,以上这些库要么相互依赖,要么依赖前面的库,所以暂时不需要再引入别的库了。(为什么说暂时?因为后面还有坑!)
所以,我们需要将上面这些库都从手机的 /system/lib/ 路径下拷贝到 armeabi-v7a 文件夹中,然后配置CMakelists.txt
sync完,点击运行
发现又报错,但是多少运行了我们在native-lib.cpp写的一句打印代码
2021-12-17 16:25:49.068 25754-25754/com.example.myopencldemo I/David: =============================================
2021-12-17 16:25:49.068 25754-25754/com.example.myopencldemo E/libOpenCLv1: [higpu]can not get property ro.board.gpu_vendor,continue to load
2021-12-17 16:25:49.068 25754-25754/com.example.myopencldemo E/linker: library "/system/vendor/lib/egl/libGLES_mali.so" ("/vendor/lib/egl/libGLES_mali.so") needed or dlopened by "/data/app/com.example.myopencldemo-MhV22tgO1Ut86wuyDuhlrg==/lib/arm/libOpenCL.so" is not accessible for the namespace: [name="classloader-namespace", ld_library_paths="", default_library_paths="/data/app/com.example.myopencldemo-MhV22tgO1Ut86wuyDuhlrg==/lib/arm:/data/app/com.example.myopencldemo-MhV22tgO1Ut86wuyDuhlrg==/base.apk!/lib/armeabi-v7a", permitted_paths="/data:/mnt/expand:/data/data/com.example.myopencldemo"]
2021-12-17 16:25:49.068 25754-25754/com.example.myopencldemo E/libOpenCLv1: load_driver(/system/vendor/lib/egl/libGLES_mali.so): dlopen failed: library "/system/vendor/lib/egl/libGLES_mali.so" needed or dlopened by "/data/app/com.example.myopencldemo-MhV22tgO1Ut86wuyDuhlrg==/lib/arm/libOpenCL.so" is not accessible for the namespace "classloader-namespace"
2021-12-17 16:25:49.068 25754-25754/com.example.myopencldemo A/libOpenCLv1: couldn't find an OpenCL implementation
2021-12-17 16:25:49.068 25754-25754/com.example.myopencldemo A/libc: Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 25754 (le.myopencldemo), pid 25754 (le.myopencldemo)
报错的意思是说华为的gpu不能获取一些属性,需要依赖 /system/vendor/lib/egl/libGLES_mali.so 这个库。
那还有啥好说的,直接把这个库从手机拷贝出来,然后再用objdump打印下它依赖的库,和它依赖的库所依赖的库,把它们都从手机复制出来。
注意:你打印出来的libGLES_mali.so依赖的库可能和我的不一样,原因前面已经说过。
libion.so
android.hardware.graphics.common@1.0.so
libnativewindow.so
liblog.so
libm.so
libc.so
libdl.so
libz.so
libc_secshared.so
libutils.so
libcutils.so
libutilscallstack.so
libc++.so
注意:这里为了让手机能正确加载android.hardware.graphics.common@1.0.so这个库,我们不得不更改它的文件名,我将它改名为 libcommon_1_0.so
以上库除了依赖更前面的库外,依赖以下库
libhidlbase.so
libhidltransport.so
libhwbinder.so
libbacktrace.so
android.hardware.graphics.common@1.1.so
上面的库除了依赖更前面的库外,依赖以下库(套娃严重)
libbinderthreadstate.so
libunwindstack.so
上面的库除了依赖更前面的库外,依赖以下库(套娃很严重)
libdexfile_support.so
liblzma.so
注意:这里为了让手机能正确加载android.hardware.graphics.common@1.1.so这个库,我们不得不更改它的文件名,我将它改名为 libcommon_1_1.so
然后将他们都拷贝到armeabi-v7a目录下
sync并运行,发现依然有报错
这里我们是将 android.hardware.graphics.common@1.1.so 重新命名为 libcommon_1_1.so ,所以APP在运行的时候找不到这个库,但是我们可以手动加载 libcommon_1_1.so
System.loadLibrary("common_1_1");
运行后,发现仍然报错
我们仍然可以手动加载libcommon_1_0.so,来解决它
运行后,终于成功!!!
其他品牌手机的搭建方法也可以参考本文。