Android VNDK限制下的解决方案

你有没有遇到过这个错误呢?

F linker: CANNOT LINK EXECUTABLE "/system/bin/xxx": library "libxxx.so" not found

首先在android生态里,一般的应用开发者,不会遇到这个问题。
系统开发者也只有在某些情况下会遇到这个问题。什么情况呢?

我们先来了解下什么是vndk以及其规则。

VNDK就是vendor NDK

SDK(software development kit),NDK(native development kit)都不陌生吧,尤其是android应用开发者来说,就是某某开发包包含了api及其规范等等使得你开发的apk可以在android上运行。
那么怎么理解,vendor native development kit呢,这要从android整个软硬件框架及其生态说起,开发者常说的android其实指的是AOSP,而一个完整的android生态,至少包含四个个部分,一个是android,一个是硬件厂家芯片,屏幕,整机等等,一个是应用开发者,一个是消费者(是硬件消费者同时也是软件,内容消费者)。
可以看到android在产品架构上起了一个承上启下的作用,将硬件厂家和开发者连接在一起。
这里有一个看似矛盾的地方,android是谷歌开源的,而谷歌是一个商业公司不是慈善机构。谷歌开源的目的是推广它的广告系统从中得利,但是太开放版本混乱体验不一致反过来会损害它的利益。所以需要在开放的同时进行控制。
如果SDK,NDK是应用开发者的开发规范,那VNDK是针对硬件厂家的开发规范。

谷歌是这样介绍VNDK的

在理想的 Android 8.0 及更高版本环境中,框架进程不加载供应商共享库,所有供应商进程仅加载供应商共享库(和一部分框架共享库),而框架进程与供应商进程之间的通信由 HIDL 和硬件 binder 控制。
主要意思是,系统分区和vendor分区隔离,尤其系统分区内的框架进程不要链接加载vendor下的so库,规则不允许这样做,强行加载会报错,就是文章开头贴的错误。谷歌以这种方式保持系统对底层的统一,限制每个硬件厂家在底层对系统的不统一的修改。
所以系统开发者如果用框架进程无论是已经存在的还是新增的去加载vendor下的库都会遇到这个问题。
可能有人会说,android是开源的,我把这个限制在源码里去掉就可以了啊,别忘了我们在之前一篇文章里说过谷歌会考试,这么做考试会不及格的。不及格就拿不到谷歌的印章,没有印章,产品想上市麻烦事有很多,所以这几行代码代价太高了,不能这么做。

如何满足VNDK的规则呢?

VNDK给出了解决方案
方案1.把vendor下的资源通过供应商进程的方式暴露出来,框架进程通过hidl或者硬件binder的方式与供应商进程通信达到访问vendor资源的目的。
方案2.如果vendor下的资源比如so库,能够从vendor下彻底脱离,也可以拷贝一份到system下,这样合理的避开了这个问题,而且还省掉了开发供应商进程的成本,以及hidl或binder通信的消耗。

在框架进程必须要加载这个库的情况下,如果vendor下的so库能彻底脱离vendor,拷贝一份在system是最佳的方案。
为什么不是直接挪到system下,而是要拷贝一份呢?因为so放在vendor下就是因为vendor要用,而vendor进程只能加载一部分谷歌允许的框架so,所以这个库如果不是谷歌允许的so只放在system下那vendor也加载不到了。这种情况两边都要放。

前几天也遇到了类似的问题

用框架进程去加载一个vendor下的共享库,vendor/lib/libxxx.so, vendor/lib64/libxxx.so,这个库是芯片厂家提供的。
报告错误,F linker: CANNOT LINK EXECUTABLE "/system/bin/xxx": library "libxxx.so" not found。
正准备将vendor下的libxxx.so拷贝到system下,修改脚本的时候注意到一个叫libxxx_system.so被拷贝到了system下,libxxx_system.so与libxxx.so同名,只是多了_system后缀。
突然一个想法闪过“libxxx_system.so就是libxxx.so在system的拷贝”,初步通过3个步骤得到了确认
1.看大小两个差不多
2.看链接的库,两个so链接的库一样,而且都是谷歌允许的框架的so
3.看符号表基本一样
然后框架进程改成链接system/lib/libxxx_system.so和system/lib64/libxxx_system.so编译通过,运行通过,问题解决。看来芯片厂家已经做了相关的预案。

仅献给遇到此问题的朋友,F linker: CANNOT LINK EXECUTABLE "/system/bin/xxx": library "libxxx.so" not found。

VNDK详细介绍:https://source.android.com/de...

相关推荐