每个算法SDK包里面都包含了inc、lib目录,也就是算法要使用到的头文件,库文件。头文件用于对外提供函数名和一些基本的需要的定义值,库文件就是算法公司封装好的代码逻辑了。
大家应该都知道,在mk文件里面每个模块(so,a,lib等)都会定义一个变量名LOCAL_MODULE,编译系统通过该变量名获取A模块的名称,然后就可以在B模块引用A模块的地方通过该名称找到A模块生成的文件,比如:LOCAL_SHARED_LIBRARIES += libarcsoft_beautyshot。所以,要调用算法库文件就需要把库文件通过mk文件预编译到代码中去。
上面这段就是预编译的mk代码:
1. LOCAL_PATH:每个Android.mk文件必须以定义LOCAL_PATH为开始。它用于在开发tree中查找源文件。宏my-dir 则由Build System提供。返回包含Android.mk的目录路径。
2. include $(CLEAR_VARS):CLEAR_VARS 变量由Build System提供。并指向一个指定的GNU Makefile,由它负责清理很多LOCAL_xxx.
ex. LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES等等。但不清理LOCAL_PATH。
这个清理动作是必须的,因为所有的编译控制文件由同一个GNU Make解析和执行,其变量是全局的。所以清理后才能避免相互影响。
3. LOCAL_MODULE:定义了模块名称。
4. LOCAL_SRC_FILES_32:需要编译的文件,只能添加一个,相当于prebuild,多添加会报错。与LOCAL_SRC_FILES不能同时使用。
5. LOCAL_MODULE_CLASS:定义模块类型,so后缀为SHARED_LIBRARIES,a后缀为STATIC_LIBRARIES。
6. LOCAL_MODULE_SUFFIX:模块后缀。
7. LOCAL_MULTILIB:定义编译出来的so是32位还是64位。
8. LOCAL_MODULE_PATH:定义模块输出路径。
9. include $(BUILD_PREBUILT):
它负责收集自从上次调用 include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。并决定编译成什么。
BUILD_STATIC_LIBRARY :编译为静态库。
BUILD_SHARED_LIBRARY :编译为动态库
BUILD_EXECUTABLE :编译为Native C可执行程序
BUILD_PREBUILT :该模块已经预先编译,目的是拷贝文件到指定目录
将这段代码写在我们存放算法头文件、库文件的目录下的mk文件中就可以将库文件预编译到out/target/XX/vendor/lib下面去了。上述代码就是截取自美颜算法目录下的Android.mk。
推荐一篇blog:https://blog.csdn.net/le_773/article/details/51714986 包含了一些其他的编译方式。
为了让自己的算法code可以复用,且不要太多太难看的插在植入点code中,我们对算法code就需要做一下再封装,便于存放集成步骤里面提到的后续一些算法的适配code。这样的话,就形成了我们自己的一个模块了。
该内容紧接在前一节预编译的mk文件的code后面。经过上述一些变量名的说明,大家应该也都知道了这些变量的含义了。新增的变量如下:
1. LOCAL_C_INCLUDES:增加头文件的索引目录。
2. LOCAL_SRC_FILES:增加要编译到模块中的文件。
3. LOCAL_SHARED_LIBRARIES:增加需要依赖的so库。
4. LOCAL_32_BIT_ONLY:新增的宏,用于限定该模块仅编译32位的so。
自己模块的mk文件内容不太复杂,但会需要在功能完善过程中逐步增加。因为往往在你引用了些头文件的时候出现,找不到头文件的编译报错,这个时候就需要在mk文件里面添加一条LOCAL_C_INCLUDES。如果你新增了一些cpp文件,就需要在mk文件里添加一条LOCAL_SRC_FILES。如果添加的头文件在编译的时候没有报错,但是提示你找不到头文件里面调用的函数的话,就需要增加一条LOCAL_SHARED_LIBRARIES来让模块找到你所依赖的模块名。
1.3.1 Camera HAL整体模块编不过,报64位so缺失。
【问题原因】F9项目平台定义的是64位编译,Camera HAL模块在编译的时候会同时编译32位so和64位so。由于客户提供的算法库有很大一部分是缺少64位so的,故在链接的时候会出现so缺失的问题。
【解决方案】F9的Camera HAL其实是运行32位的。64位只是编译时候需要而已,并不会在使用的时候真正运行到。故只需要把所有依赖关系的so库都限定在32位即可。参考高通项目代码(CAM HAL里面做了32位的限定),在F9项目中定义LOCAL_32_BIT_ONLY := $(BOARD_MTK_CAMERA_32BIT_ONLY)参数用于限定这些依赖的so编译在32位上。
如果确定哪些mk需要添加so,其实没有便捷的方法,只能通过链接关系一一往上排查。可以画一张图来确认,确认完之后添加进去,基本可以达到目标。
1.3.2 ExtImgProc所在模块已经添加模块链接,但还是报异常
【问题现象】直接使用三方算法库的ExtImgProc的mk文件中已经添加了LOCAL_SHARED_LIBRARIES += libarcsoft_facebeauty算法模块的链接,但是依然会报undefined reference的异常:
undefined reference to 'ArcsoftFaceBeauty::processImage(android::sp
【解决方案】在报错的模块中也添加了这句算法模块的链接,就不会报异常了。比如当时在middleware/v1/client和middleware/v1/adapter下面的makefile都添加了LOCAL_SHARED_LIBRARIES += libarcsoft_facebeauty。
这类问题只要发生的时候,发生1个地方加1个地方就行,不用全部排查下来。
1.3.3 出现Camera图标消失问题
【问题原因】通过MTKLogger可以抓到开机时候CameraDevice在加载so的一句错误log,提示找不到算法的so。
【解决方案】BUILD_PREBUILT中module名字一定要和预置的lib文件一样,否则会造成CameraDevice load的时候找不到该so。