Android开发> 集成so库
上述文章是对本文的补充。
当我们需要在自己的代码中使用第三方提供的一些接口函数时,我们该如何加入?作者在写这比安文章前遇到了一个问题:需要在自己的HAL层中引用第三饭提供的算法库即so库;这个问题是作者第一次遇到,以往都是自己写一些代码编一些so,然后引用的。对于这个问题,作者也问了度娘,但搜索到的方法各式各样,且有些还是FW层 或app层的一些方法。这里作者对所使用的方法进行了一些总结。
一、问题前提
作者需要在HAL层(HIDL服务) 引用第三方so库;
二、第三方提供资料
第三方提供的资料包含 : .so 文件 和 .h文件;
三、添加SO编译
这里作者当前模块是使用Android.mk 进行编译的; 需要在mk文件中引入第三方so进行编译。这里作者尝试了几种方法,读者根据自身条件或可行性进行使用测试。
方法1: 将第三方so编译成本地so。
添加编译方式在mk中添加内容如下:
include $(CLEAR_VARS)
LOCAL_MODULE := libwater
LOCAL_SRC_FILES :=$(LOCAL_PATH)/lib64/libwater.so
LOCAL_MULTILIB := 64
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
LOCAL_PROPRIETARY_MODULE := false
LOCAL_MODULE_PATH := $(TARGET_OUT)/lib
LOCAL_MODULE_TAGS := optional
include $(BUILD_PREBUILT)
第1行:清理编译变量;
第2行:编译生成的目标文件名,这里就是需要生成的库名;
第3行:编译所使用的源文件,可以是.so,或.cpp等源文件;
第4行:声明生成64位 或32位库;
第5行:声明模块是 共享库的形式;
第6行:so的形式;
第7行:是否专有模块,false:否
第8行:输出目标的路径,这个可以自定义,一般是放到“vendor/lib” 或“vendor/lib64”;
原因是:编译打包时,会将so 一起打包进vendor.img,后续引用就不会提示找不到; 或者测试时可手动 adb push;
第9行:目标标记;
第10行:生成目标的类型。
注意:
将编译生成的so,添加到引用模块的 “LOCAL_SHARED_LIBRARIES” 中;如:
LOCAL_SHARED_LIBRARIES += \
libwater
方法2:使用 LOCAL_LDFLAGS 参数编译带-L 和-l参数
在需要引用的模块中添加下面语句:
LOCAL_LDFLAGS := -L./lib64/ -lwater
-L:表示so库所在路径位置;
-l:表示so库名,不带前缀lib 和 后缀.so;
方法3:使用 LOCAL_LDFLAGS 不带参数
在需要引用的模块中添加下面语句:
LOCAL_LDFLAGS += LOCAL_LDFLAGS += $(LOCAL_PATH)/lib64/libwater.so
直接引用so库,如有多个 可分行重复语句书写。
四、头文件引用
在引用SO编译的位置添加i安眠语句:
LOCAL_C_INCLUDES += \
./include
五、编译
编译前提android源码需要整编过一次;
进入android源码根目录运行下面命令:
source build/envsetup.sh
lunch xxx
然后进入到需要编译的模块目录下,运行:
mma
或
mm
或
mmm
六、接口调用测试
在需要调用的的cpp源码中,添加 头文件引用;
如: #include “water.h”
在添加接口调用,如:
int ret = waterstart();
七、编译出错
错误1:如果编译时提示的错误如下图:
解决方法:由于引用的时第三方64位so,系统可能默认对第三方库使用32位进行编译,所以会提示架构不同; 需要在引用so之前添加一句“LOCAL_MULTILIB := 64”,声明时64位,即可。
八、验证
编译成功后可看到 输出的路径位置;
使用adb push命令将文件放到vendor/bin/hw目录下,重启设备运行;
查看输出的log即可。
补充说明:
补充1: 当引用的so库存在在system目录下,但是需要引用的确需在vendor目录下时;可通过预编译的形式;
编写Android.bp文件,以libstdc++.so为例,增加下面内容:
cc_prebuilt_library_shared {
name: "libstdc++_dr",
stem: "libstdc++",
vendor: true,
multilib: {
lib64: {
srcs: ["lib64/libstdc++.so"],
},
},
check_elf_files: false,
}
如果是引用第3方so的,也可使用预编译这一方法。