[实战笔记]系统编译 您所在的位置:网站首页 台湾rnb歌手 [实战笔记]系统编译

[实战笔记]系统编译

2023-08-24 17:29| 来源: 网络整理| 查看: 265

目录

前言 —— 需求提出

Android 8.0-  —— Android.mk实现条件编译

Android 9.0+ —— Android.bp实现条件编译

扩展:Android 9.0+ —— Android.bp实现自定义条件编译

本人正在学习中。此篇文章如有不正之处,欢迎指正讨论!

前言 —— 需求提出

最近在协助完成模块优化的时候,有个需求如下:

依赖结构:A B C……等多个平台共用一个自定义系统模块

随后优化此模块中内容,改动需要跟随A平台进行系统迭代测试,但希望BC等其他平台不受此优化内容影响

基于上面的需求,整理了一下条件:

1.平台系统版本包括Android 8.0、9.0。

2.自定义系统模块功能已经在源码打点完毕,尽可能少地改动系统源码(否则要多个平台都修改)。

3.不同平台可快速进行优化方案和非优化方案的切换,便于在不同阶段的各个平台能不受影响快速切换方案。

因此想出了以下做法:

1.保证优化后的类名和包名一致,可以放到包名以上的其他目录中。        —— 确保系统源码中的打点无需改动。

如自定义系统模块中优化前的类和包名为:(module_path)/hotkey/service/core/java/com/android/server/policy/HotKey.java

自定义系统模块中优化后的类和包名为:(module_path)/audio/service/core/java/com/android/server/policy/HotKey.java

如此一来,HotKey的类名和包名与原来一致,系统中引用到HotKey的地方依旧只需要import com.android.server.policy.HotKey; 无需变动。

2.在Android.mk和Android.bp中完成条件编译。   ——  兼容不同版本系统平台,根据条件快速切换优化方案。

下面就想方法解决这个问题吧!

Android 8.0-  —— Android.mk实现条件编译

先给出一份8.0系统framework下的mk文件(framework/base/service/core):

LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := services.core …… LOCAL_SRC_FILES += \ $(call all-java-files-under,java) \ java/com/android/server/EventLogTags.logtags \ java/com/android/server/am/EventLogTags.logtags \ ../../../../system/netd/server/binder/android/net/INetd.aidl \ ../../../../system/netd/server/binder/android/net/metrics/INetdEventListener.aidl \ ../../../native/cmds/installd/binder/android/os/IInstalld.aidl \ # patch start $(custom_module_files) \ # patch end …… include $(BUILD_STATIC_JAVA_LIBRARY)

在源码中mk中加入 $(module_files),在自定义系统模块的mk中完成 module_files 的定义,将改动尽量放到系统自定义模块下。

Android.mk不必多说,通过在mk里设立变量,即可使用ifeq、ifdef等判断值,进行条件编译。如定义:

OPTIMIZE := true

 随后修改mk参与编译的文件,如下:

custom_module_files := \ …… # patch start ifeq ($(OPTIMIZE),true) custom_module_files += \ (custom_module_path)/audio/services/core/java/com/android/server/policy/HotKey.java else custom_module_files += \ (custom_module_path)/hotkey/services/core/java/com/android/server/policy/HotKey.java endif # patch end

其中audio目录下的HotKey.java是优化后待测试的代码,而policy目录下的HotKey则是未优化的稳定代码。通过定义mk中的变量,就可以完成mk文件的条件编译了。

Android 9.0+ —— Android.bp实现条件编译

Android在7.0引入 ninja 编译系统,8.0引入Android.bp替代Android.mk,9.0强制使用Android.bp作为编译配置。

解决完8.0的编译问题,准备着手9.0的编译问题了。出于一样的想法,在bp里完成条件编译,然后和mk处理方式一样,通过开关决定参与编译的文件,即可解决此问题。但是Android.bp实际上是一个纯粹的json配置文件,没有条件、分支等流程结构,因此即便使用自带的androidmk工具想要将Android.mk快速转成Android.bp,也会发现流程语句并不起效果。为了解决此问题,google将条件编译进行分家,Android.bp负责纯粹配置,引入Go文件负责进行流程结构判断。

这样一来思路就清楚了:

下面用代码实现:

1.自定义模块custommodule下Android.bp定义两个方案(优化和未优化),如:

# patch start filegroup { name: "custom_optimize", srcs: [ "audio/services/core/java/com/android/server/policy/HotKey.java", ], } filegroup { name: "custom_origin", srcs: [ "hotkey/services/core/java/com/android/server/policy/HotKey.java", ], } # patch end

2.添加用于自定义系统模块条件编译的Go文件。如在自定义模块名字为customsystem,则在customsystem目录下创建customsystem.go,内容如下:

package customsystem import ( "android/soong/android" "android/soong/java" "fmt" ) //注册module模板,存放默认属性 func init() { android.RegisterModuleType("custom_optimize_default", custom_optimize_go) } func custom_optimize_go() android.Module { module := java.DefaultsFactory() android.AddLoadHook(module, custom_optimize_append_properties) return module } func custom_optimize_append_properties(ctx android.LoadHookContext) { type props struct { Srcs []string } p := &props{} sdkVersion := ctx.AConfig().PlatformSdkVersionInt() fmt.Println("sdkVersion:", sdkVersion) if sdkVersion >=28 { //after P p.Srcs = append(p.Srcs, ":custom_optimize") } else { p.Srcs = append(p.Srcs, ":custom_origin") } ctx.AppendProperties(p) }

3.framework下Android.bp加入自定义模块声明(framework/base/service/core/Android.bp):

# patch start custom_optimize_default{ name: "custom_optimize_default", } # patch end java_library_static { name: "services.core.unboosted", # patch start defaults: [ "custom_optimize_default", ], # patch end aidl: { …… }, srcs: [ …… ], …… }

 这样子就完成了一次条件编译,此处使用的条件是Android版本。如果需要其他变量作为判断条件,可以查看out/soong/soong.variables文件,里面是系统中提供的所有环境变量,如当前系统Android版本、是否调试版本、架构、路径等等:

{ "Platform_version_name": "9", "Platform_sdk_version": 28, "Platform_sdk_codename": "REL", "Platform_sdk_final": true, "Allow_missing_dependencies": false, "Debuggable": false, "Eng": false, "DeviceArch": "arm", "DeviceArchVariant": "armv7-a-neon", "DeviceCpuVariant": "cortex-a9", "DeviceAbi": ["armeabi-v7a","armeabi"], "DeviceSecondaryArchVariant": "", "DeviceSecondaryCpuVariant": "", "HostArch": "x86_64", "HostSecondaryArch": "x86", "HostStaticBinaries": false, "CrossHost": "windows", "CrossHostArch": "x86", "CrossHostSecondaryArch": "x86_64", …… } 扩展:Android 9.0+ —— Android.bp实现自定义条件编译

上一部分做了一个用系统内环境变量条件编译的实例,不过等等,好像和一开头的需求不是很符合?

想一想,仅用sdkVersion进行判断,那么对于所有Android9.0的平台来说只能做统一处理,连区分平台都做不到,更何况区分同code的不同平台了。

那么扩展场景来了:如何打入一个系统环境变量,并通过mk文件赋值,让我们的条件编译真正按照平台生效呢?

翻了资料,全程耗时一周,打通了一条路,原理剖析后续补上,直接上code。(具体可以戳传送门瞅瞅这位大大写出来的通路图 --> https://blog.csdn.net/u012188065/article/details/89352166)

1.在平台mk中,定义mk变量。(此处平台mk选择的是BoardConfig.mk, 路劲device/(厂商)/(平台)/BoardConfig.mk

# patch start OPTIMIZE := true # patch end

2.新增bool类型go变量。路径build/soong/android/variable.go

type productVariables struct { …… // patch start Optimize *bool `json:",omitempty"` // patch end }

3.建立go变量和mk变量的json映射关系,让go变量可以获取到mk中定义的变量值。路径build/make/core/soong_config.mk

…… # patch start $(call add_json_bool, Optimize, $(filter true, $(OPTIMIZE))) # patch end # 这句等同于: # bool Optimize = (OPTIMIZE == true) ……

4.定义go方法,返回go变量的值。路径:build/soong/android/config.go

…… # patch start func (c *deviceConfig) Optimize() bool { return Bool(c.config.productVariables.Optimize) } # patch end ……

完成了以上四步后,mk变量就成功映射到go文件中,并生成系统环境变量。

在编译之后可以查看out/soong/soong.variables文件,确认是否生成环境变量,赋值是否正确。

基于上一部分的成果,我们来修改一下实现,完成我们的需求:

修改customsystem.go,如下:

…… func custom_optimize_append_properties(ctx android.LoadHookContext) { type props struct { Srcs []string } p := &props{} // 修改成自定义条件 optimize := ctx.DeviceConfig().Optimize() fmt.Println("mk OPTIMIZE:", optimize) if optimize { p.Srcs = append(p.Srcs, ":custom_optimize") } else { p.Srcs = append(p.Srcs, ":custom_origin") } ctx.AppendProperties(p) } ……

修改到这里,就完全结束了。现在只需要编译看看,验证效果。

相关原理剖析会另起一篇,未完待续……

——————————————————————————————————————

参考资料:

① 少侠的崛起 - 产品.mk控制android.bp选择性编译 - https://blog.csdn.net/u012188065/article/details/89352166

② 秋少 - Android系统开发进阶-Android编译系统介绍 - https://qiushao.net/2020/02/06/Android%E7%B3%BB%E7%BB%9F%E5%BC%80%E5%8F%91%E8%BF%9B%E9%98%B6/Android%E7%BC%96%E8%AF%91%E7%B3%BB%E7%BB%9F%E4%BB%8B%E7%BB%8D/

(③ 感谢海思的小抄!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有