#星计划# OH编译构建分析 - 依赖关系检查 原创 精华
背景
OHOS的编译构建系统是由sh脚本(或bat脚本),python脚本,Gn和Ninja工具组成的编译构建框架。总体编译构建流程是根据产品配置,生成具体依赖关系,然后使用Gn配置构建目标,通过Gn生成ninja文件,然后执行ninja生成二进制,最后打包生成镜像的过程。本篇主要涉及配置文件规则和编译初期的规则检查。
编译初期(prebuild)
简单解读(基本规则)
-
编译构建的重要组成部分:
OHOS的编译构建以下三个仓是编译构建重要的三个仓:
- productdefine:产品配置仓,包含了基础部件的组成形态,主要看/produdctdefine/common/base目录下的文件
- vendor:各厂家的产品仓,如大家最熟悉的/vendor/hihope/rk3568,编译命令指定–product-name来寻找对应的产品
- build:编译构建仓,包括规范,检查工具,编译构建脚本等等,OHOS编译构建的核心仓
-
关注重点
-
BUILD.gn:每个模块都对应一个BUILD.gn文件。可以使用提供的模板,也可以使用gn语法规则自定义编写。
例子:
ohos_shared_library示例:
``` import("//build/ohos.gni") ohos_shared_library("helloworld") { sources = [] include_dirs = [] cflags = [] cflags_c = [] cflags_cc = [] ldflags = [] configs = [] deps =[] # 部件内模块依赖 # 跨部件模块依赖定义, # 定义格式为 "部件名:模块名称" # 这里依赖的模块必须是依赖的部件声明在inner_kits中的模块 external_deps = [ "part_name:module_name", ] output_name = "" # 可选,模块输出名 output_extension = "" # 可选,模块名后缀 module_install_dir = "" # 可选,缺省在/system/lib64或/system/lib下, 模块安装路径,模块安装路径,从system/,vendor/后开始指定 relative_install_dir = "" # 可选,模块安装相对路径,相对于/system/lib64或/system/lib;如果有module_install_dir配置时,该配置不生效 install_images = [] # 可选,缺省值system,指定模块安装到那个分区镜像中,可以指定多个 part_name = "" # 必选,所属部件名称 } ```
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
ohos_executable示例:
ohos_executable模板属性和ohos_shared_library基本一致
注意:可执行模块(即ohos_executable模板定义的)默认是不安装的,如果要安装,需要指定install_enable = true
ohos_prebuilt_etc示例:
``` import("//build/ohos.gni") ohos_prebuilt_etc("etc_file") { source = "file" deps = [] # 部件内模块依赖 module_install_dir = "" #可选,模块安装路径,从system/,vendor/后开始指定 relative_install_dir = "" #可选,模块安装相对路径,相对于system/etc;如果有module_install_dir配置时,该配置不生效 install_images = [] # 可选,缺省值system,指定模块安装到那个分区镜像中,可以指定多个 part_name = "" # 必选,所属部件名称 } ```
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
更多详细的模板信息请参照模块配置规则。
-
bundle.json:定义了子系统包含的部件。每个部件定义它所包含的模块目标component.build.sub_component,以及部件间交互的接口component.build.inner_kits,测试用例component.build.test_list。部件包含的模块目标component.build.sub_component是必须要说明的。原来老版本有ohos.build,后面全部整改为bundle.json
新增部件的大致步骤就是在在部件目录中新建一个bundle.json,然后再在//vendor/{product_company}/{product-name}/config.json中添加对应的部件,直接添加到原有部件后即可。具体流程请参照编译构建指导的配置规则与新增并编译不同配置,其中详细的介绍了如何添加一个模块、部件或者子系统。
-
vendor里的config.json:指明了产品名,产品厂商,产品设备,版本,要编译的系统类型,以及产品包含的子系统。
其他更详细内容请查看:build: Compilation and building framework and scripts | 编译构建框架和脚本 (gitee.com)
-
常见Q&A解读(错误处理)
常见七类问题:
- subsystem_components
错误原因:
子系统配置清单中的子系统名和部件配置清单中的子系统名不一致;或bundle.json中的部件名和部件配置清单中的部件名不一致
解读:
“subsystem” 代表产品部件列表(config.json)配置的子系统名错误
“component”代表产品部件列表(config.json)配置的部件名错误
此类问题代表vendor\xxx\build\component_config\system\XXX\part_config.json 文件中配置的子系统名或者部件名错误,component 代表部件名配置错误, subsystem 代表子系统名配置错误
整改方法:
如果是子系统名配置错误,请排查 part_config.json中配置的子系统名是否在subsystem_config.json中有配置
OHOS的subsystem_config.json路径:build/subsystem_config.json
如果是部件名配置错误,请排查part_config.json文件中的部件名是否和该部件的bundle.json中的部件名配置一致
- bundle_subsystem_error
错误原因:
bundle.json中定义的子系统名和子系统配置清单中的不一致
具体日志
解读:
该问题代表bundle.json里的子系统名称配置和subsystem_config.json配置不一致,需要整改bundle.json的子系统名称
bundle.json路径:foundation/ability/ability_base/bundle.json
整改方法:
请检查本部件bundle.json中是否有配置子系统并且配置的子系统名与subsystem_config.json中一致,若不一致,请将bundle.json中的子系统名改为subsystem_config.json中的子系统名
- gn_part_or_subsystem_error
错误原因:
BUILD.gn中定义的部件名或子系统名与bundle.json中定义的不一致
具体日志:
解读:
该问题代表模块的BUILD.gn里面配置的子系统名或者部件名不准确,需要和部件bundle.json对齐
BUILD.gn路径:foundation/distributedhardware/distributed_audio/hdf_service/distributed_audio/hdi_service/audio/v1_0/BUILD.gn
编译目标:libaudio_manager_daudio_primary_service_1.0
整改方法:
将本部件下该模块BUILD.gn中的部件名与子系统名改为本部件bundle.json中的子系统名和部件名
如果已确认BUILD.gn和bundle.json中的子系统名和部件名一致,请再确认part_config.json中是否正确配置了该子系统名和部件名
part_config.json路径:(和编译命令中abi-type、device-type参数一致)
系统组件:
vendor/xxx/build/component_config/system/XXX/part_config.json
vendor/xxx/build/component_config/system/XXX/part_config.json
芯片组件:
vendor/xxx/build/component_config/chipset/XXX/part_config.json
vendor/xxx/build/component_config/chipset/XXX/part_config.json
- deps_added_external_part_module
错误原因:
BUILD.gn中使用deps依赖了外部部件的模块
具体日志:
解读:
该问题代表该模块通过deps依赖了部件外的模块,应该用external_deps依赖
BUILD.gn路径:foundation/distributedhardware/distributed_camera/services/channel/BUILD.gn
编译目标:distributed_camera_channel
deps中依赖的外部模块:foundation/distributedhardware/distributed_hardware_fwk/interfaces/inner_kits:libdhfwk_sdk
整改方法:
将该模块从deps转移到external_deps中
注:deps中使用的是"路径:模块名",而改到external_deps中是使用 “部件名:模块名” 的方式
- external_deps_added_self_part_module
错误原因:
使用external_deps依赖了本部件的模块
具体日志:
解读:
该日志代表该模块通过external_deps依赖了本部件模块,需要改成deps依赖
BUILD.gn路径:foundation/distributeddatamgr/preferences/frameworks/js/napi/preferences
external_deps中依赖的本部件:preferences
整改方法:
将该依赖从external_deps转移到deps中
- external_deps_bundle_not_add
**错误原因:**BUILD.gn中外部依赖了其他部件的模块,但是bundle.json中没有添加这个部件
注:对于三方部件,如果BUILD.gn里面用的是deps依赖,那在bundle.json中需要加到third_party中,如果使用的是external_deps依赖的三方部件,那在bundle.json中需要加到components中
具体日志:
解读:
该日志代表该模块(BUILD.gn)里面依赖的外部部件,但没有在部件bundle.json声明,需要在bundle.json声明。
BUILD.gn路径:base/theme/wallpaper_mgr/frameworks/kits/extension/BUILD.gn
编译目标:wallpaperextension
依赖的部件:window_manager
bundle.json路径:base/theme/wallpaper_mgr/bundle.json.
整改方法:
将被依赖的外部部件添加到bundle.json中的deps:components字段中,如上述例子中,需要将”input”和”window_manager”添加到bundle.json中
- third_deps_bundle_not_add
错误原因:
BUILD.gn中依赖了三方部件,但是部件bundle.json中没有添加该三方部件
具体日志:
解读:
该日志代表该模块(BUILD.gn)里面依赖的三方部件,没有在部件bundle.json中的third_party中声明,需要在bundle.json声明。
BUILD.gn路径:base/security/device_auth/services
编译目标:deviceauth_service
依赖的三方部件:cjson
bundle.json路径:vendor_baltimore_musl/base/security/device_auth/bundle.json
整改方法:
将被依赖的三方部件添加到bundle.json中的deps:third_party字段中,如上述例子中,需要将 “cjson” 添加到bundle.json中
相当全的方法总结,必须收藏!