AndroidO Treble架构下的接口文件编译

HIDL是一种接口定义语言,描述了HAL和它的用户之间的接口。同aidi类似,我们只需要为hal定义相关接口,然后通过hidl-gen工具即可自动编译生成对应的C++或者java源文件,定义hal接口的文件命名为xxx.hal,为了编译这些.hal文件,需要编写相应的Android.bp或者Android.mk文件:
1. Android.bp文件用于编译C++;
2. Android.mk文件用于编译Java;
生成子Android.mk和Android.bp文件
所有的HIDL Interface 都是通过一个.hal文件来描述,为了方便编译生成每一个子hal。Google在系统默认提供了一个脚本update-makefiles.sh,位于hardware/interfaces/、frameworks/hardware/interfaces/、system/hardware/interfaces/、system/libhidl/。以hardware/interfaces/里面的代码为实例做介绍:

#!/bin/bash  

source system/tools/hidl/update-makefiles-helper.sh  

do_makefiles_update \  
  “android.hardware:hardware/interfaces” \  
  “android.hidl:system/libhidl/transport”  

这个脚本的主要作用:根据hal文件生成Android.mk(makefile)和Android.bp(blueprint)文件。在hardware/interfaces的子目录里面,存在.hal文件的目录,都会产生Android.bp和Android.mk文件。详细分析如下:
1. source system/tools下面的update-makefiles-helper.sh,然后执行do_makefiles_update
2. 解析传入进去的参数。参数android.hardware:hardware/interfaces:
    android.hardware: android.hardware表示包名。
    hardware/interfaces:表示相对于根目录的文件路径。
会输出如下LOG:

Updating makefiles for android.hardware in hardware/interfaces.  
Updating ….  

3.获取所有的包名。通过function get_packages()函数,获取hardware/interfaces路径下面的所有hal文件所在的目录路径,比如子目录power里面的hal文件的路径是power/1.0,加上当前的参数包名hardware/interfaces,通过点的方式连接,将nfc/1.0+hardware/interfaces里面的斜线转换成点,最终获取的包名就是 [email protected],依次类推获取所有的包名。
4.执行hidl-gen命令.将c步骤里面获取的参数和包名还有类名传入hidl-gen命令,在hardware/interfaces/power/1.0目录下产生Android.mk和Android.bp文件。
    Android.mk: hidl-gen -Lmakefile -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport [email protected]

编译最终在./out/target/common/gen/JAVA_LIBRARIES目录下生成Java源文件。

    Android.bp: hidl-gen -Landroidbp -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport [email protected]


编译最终在out/soong/.intermediates/hardware/interfaces目录下生成Java源文件。

5.在hardware/interfaces的每个子目录下面产生Android.bp文件,文件内容主要是subdirs的初始化,存放当前目录需要包含的子目录。比如hardware/interfaces/power/下面的Android.bp文件。

// This is an autogenerated file, do not edit. 

subdirs = [ 

    "1.0", 

    "1.0/default", 

    "1.0/vts/functional", 

]

经过以上步骤,就会在对应的子目录产生Android.mk和Android.bp文件。这样以后我们就可以执行正常的编译命令进行编译了。比如mmm hardware/interfaces/power/,默认情况下,在源码中,Android.mk和Android.bp文件已经存在。
hidl-gen工具
在Treble架构中,系统定义的所有的.hal接口,都是通过hidl-gen工具转换成对应的代码。比如hardware/interfaces/power/1.0/IPower.hal,会通过hidl-gen转换成out/soong/.intermediates/hardware/interfaces/power/1.0/[email protected]_genc++/gen/android/hardware/power/1.0/PowerAll.cpp文件。
hidl-gen源码路径:system/tools/hidl,是在ubuntu上可执行的二进制文件。
使用方法:hidl-gen -o output-path -L language (-r interface-root) fqname
参数含义:
    -L: 语言类型,包括c++, c++-headers, c++-sources, export-header, c++-impl, java, java-constants, vts, makefile, androidbp, androidbp-impl, hash等。hidl-gen可根据传入的语言类型产生不同的文件。fqname:完全限定名称的输入文件。比如本例中[email protected],要求在源码目录下必须有hardware/interfaces/power/1.0/目录。
        对于单个文件来说,格式如下:package@version::fileName,比如[email protected]::types.Feature。
        对于目录来说。格式如下package@version,比如[email protected]
    -r: 格式package:path,可选,对fqname对应的文件来说,用来指定包名和文件所在的目录到Android系统源码根目录的路径。如果没有制定,前缀默认是:android.hardware,目录是Android源码的根目录。
    -o : 存放hidl-gen产生的中间文件的路径。我们查看hardware/interfaces/power/1.0/Android.bp,可以看到,-o参数都是写的$(genDir),一般都是在out/soong/.intermediates/hardware/interfaces/power/1.0/下面,根据-L的不同,后面产生的路径可能不太一样,比如c++,那么就会就是
out/soong/.intermediates/hardware/interfaces/power/1.0/[email protected]_genc++/gen,
如果是c++-headers,那么就是
out/soong/.intermediates/hardware/interfaces/power/1.0/[email protected]_genc++_headers/gen。
对于实例来说,fqname是:[email protected],包名是android.hardware,文件所在的目录是hardware/interfaces。例子中的命令会在out/soong/.intermediates/hardware/interfaces/power/1.0/下面产生对应的c++文件。

在hardware/interfaces/graphics/composer目录下mm编译将生成:
[email protected] .so
[email protected]
[email protected]
[email protected]
他们之间的关系如下图所示:

[email protected]为hal进程的可执行文件,在[email protected]是hal进程启动的配置脚本文件:

也就是说AndroidO的Treble架构下,所有hal都运行在独立的进程空间:

AndroidO之前版本的Hal都是编译为so库,然后动态链接到各个Framework Server进程,经过hidl化后,所有的Hal都运行在自己的Hal Process中,与Framework Server进程分离,这样既方便系统升级,也有利于系统稳定性,hal crash了也不至于导致Framework Server Process crash。那AndroidO下的hal库变化了吗?没有,google提供了passthou模式用于兼容之前的hal实现方式。

猜你喜欢

转载自blog.csdn.net/marshal_zsx/article/details/80293033