1# OpenHarmony部件编译构建规范指导 2 3## OpenHarmony部件编译构建规范本地检查脚本使用指导 4 5### 介绍 6 7部件编译构建规范本地检查脚本用于检查openharmony编译构建中不规范的问题,详细检查问题见[OpenHarmony部件编译构建规范修改指导](#openharmony部件编译构建规范修改指导) 8### 使用方法 9 10```shell 11python3 csct.py [-p path] 12``` 13 14#### 示例 15 16若要检查openharmony全量的不规范问题,可以在openharmony根目录使用以下命令。 17 18```shell 19python3 build/tools/component_tools/static_check/csct.py 20``` 21 22若要检查某个目录下的不规范问题,可以在openharmony根目录使用以下命令。 23 24```shell 25python3 build/tools/component_tools/static_check/csct.py -p [要检查的目录] 26 27example: 28python3 build/tools/component_tools/static_check/csct.py -p base/global 29``` 30 31#### 使用前须安装的python库 32 33- prettytable 34- pandas 35- openpyxl 36 37#### 结果查看 38 39程序执行结束后会在执行目录生成一个out目录,有excel和txt类型的结果,建议通过excel进行查看。 40 41## OpenHarmony部件编译构建规范修改指导 42 43关于完整的OpenHarmony部件编译构建规范,请点击 44[这里](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/subsystems/subsys-build-component-building-rules.md) 45### 规则2.1 部件描述文件中字段须准确。 46 47- name 48 49 类型:string。部件的HPM(鸿蒙包管理器)包名称,必填。命名规则:@{organization}/{component_name}。“component_name“为部件的名称,须满足规则1.1。 50 51 52- version 53 54 类型:string。部件版本号,必填,命名和升级跟随OpenHarmony版本号。 55 56- destPath 57 58 类型:string。部件源码的根目录,必填。部件的根目录须独立唯一,不允许存在多个根目录。 59 60 61- component:name 62 63 类型:string。部件名,必填。须满足规则1.1。 64 65 66- component:subsystem 67 68 类型:string。部件归属的子系统名称,必填,子系统名为小写英文字母组合、不使用下划线。 69 70 71- component:syscap 72 73 类型:string list。可选。命名规则:大驼峰,“SystemCapability.Subsystem.部件能力.子能力(可选)”,如SystemCapability.Media.Camera , SystemCapability.Media.Camera.Front。 74 75- component:features 76 77 类型:string list,部件可配置的特性,可选,命名须满足规则1.2。 78 79 80- component:adapted_system_type 81 82 类型:string list。部件适用的系统类型,必填,值为“mini、small和standard",可同时支持多种。 83 84 85- component:rom 86 87 类型:string。ROM基线值,必填,单位默认为KByte。 88 89 90- component:ram 91 92 类型:string。RAM基线值,必填,单位默认为KByte。 93 94 95- component:deps 96 97 类型:string list。deps对象描述了部件的外部依赖,必填,包括其他部件和三方开源软件,应该与部件编译脚本中依赖一致。 98 99 100 #### 修改指导: 101 102 以一个错误 bundle.json 为例: 103 104 ```python 105 { 106 "name": "sensor_lite", # 部件的HPM名,规则为 @{organization}/{component_name} 107 "description": "Sensor services", 108 "version": "3.1", # 版本号,版本号与OpenHarmony版本号一致 109 "license": "MIT", 110 "publishAs": "code-segment", 111 "segment": { 112 "destPath": "" # 部件源码根目录,不能为空 113 }, 114 "scripts": {}, 115 "component": { 116 "name": "SensorLite", # 部件名应该与 HPM 名的 component_name 部分一样,并且为内核命名风格。 117 "subsystem": "Sensors", # 必须全小写字母,且不含有下划线 118 "syscap": [ 119 "SystemCapability.Sensors.sensor.lite" # 必须大驼峰风格 120 ], 121 "features": [], 122 "adapted_system_type": [ "liteos_m" ], # 轻量(mini)小型(small)和标准(standard),可以是多个 123 "rom": "", # 部件ROM值, 不能为空 124 "ram": "", # 部件RAM估值, 不能为空 125 "deps": { 126 "components": [ 127 "samgr_lite", 128 "ipc_lite" 129 ], 130 } 131 "build": { 132 "sub_component": [ 133 "//base/sensors/sensor_lite/services:sensor_service", 134 ], 135 "inner_kits": [], 136 "test": [] 137 } 138 } 139 } 140 ``` 141 142 根据上面的错误标记,应该修改为如下: 143 ```python 144 { 145 "name": "@ohos/sensor_lite", # 添加前缀 '@ohos/' 146 "description": "Sensor services", 147 "version": "3.2", # 目前 OpenHarmony 版本号为 3.2 148 "license": "MIT", 149 "publishAs": "code-segment", 150 "segment": { 151 "destPath": "base/sensors/sensor_lite" # 部件源码根目录(相对路径) 152 }, 153 "scripts": {}, 154 "component": { 155 "name": "sensor_lite", # 前后统一,内核命名风格 156 "subsystem": "sensors", # 全小写字母组合 157 "syscap": [ 158 "SystemCapability.Sensors.Sensor.Lite" # 大驼峰风格 159 ], 160 "features": [], 161 "adapted_system_type": [ "small" ], # 该部件仅支持小型(small)系统 162 "rom": "92KB", # 根据实际情况填写 163 "ram": "~200KB", # 根据实际情况估算,'~'表示大概 164 "deps": { 165 "components": [ 166 "samgr_lite", 167 "ipc_lite" 168 ], 169 } 170 "build": { 171 "sub_component": [ 172 "//base/sensors/sensor_lite/services:sensor_service", 173 ], 174 "inner_kits": [], 175 "test": [] 176 } 177 } 178 } 179 ``` 180 181 182### 规则3.1 部件编译脚本中只允许引用本部件的路径,禁止引用其他部件的绝对或相对路径。 183 184部件间的依赖都必须使用“externel_deps”,部件编译目标的变量sources、include_dirs、configs、public_configs、deps、public_deps引用其他部件的相对和绝对路径属于非法引入依赖: 185 186- sources 187 188 sources只允许包含本部件的源码,包含其他部件的源码破坏了部件源码目录独立的原则。 189 190- include_dirs 191 192 include_dirs只允许引用本部件的头文件搜索路径,编译单元对其他部件的接口的依赖都通过externel_deps自动导入。 193 194- configs 195 196 configs只允许引用本部件的配置路径,引用其他部件的configs可能会引入接口依赖。 197 198- pulic_configs 199 200 同configs,引用其他部件的configs可能会引入接口依赖。 201 202- deps 203 204 deps只允许用于部件内模块的依赖,直接引用其他部件的模块可能会导致依赖其他部件的内部模块和接口。 205 206 例: 207 208 base/foos/foo_a/BUILD.gn 209 210 ```c 211 deps = [ "//base/foo/foo_b:b" ] // Bad, 绝对路径依赖其他部件 212 deps = [ "../../foo_b:b" ] // Bad, 相对路径依赖其他部件 213 ``` 214 215 例外:对三方开源软件和build目录下的引用除外。 216 217- public_deps 218 219 同deps,public_deps只允许用于部件内模块的依赖。 220 221 222 223#### 修改建议: 224 2251.若绝对路径引用的是本部件的内容,则应改为使用相对路径。 226 227例如foundation/systemabilitymgr/samgr/services/samgr/native/BUILD.gn中 228 229```c 230config("distributed_store_config") { 231 visibility = [ ":*" ] 232 include_dirs = 233 [ "//foundation/systemabilitymgr/samgr/services/samgr/native/include" ] 234} 235``` 236 237以上include_dirs中的引用自己的内容使用了绝对路径是错误的,建议修改为: 238 239```c 240 [ "include" ] 241``` 242 2432.若绝对引用的是其他部件的内用,则应改为external_deps的方式。 244 245例如foundation/bundlemanager/bundle_framework_lite/services/bundlemgr_lite/tools/BUILD.gn中 246 247```c 248 deps = [ 249 "${appexecfwk_lite_path}/frameworks/bundle_lite:bundle", 250 "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared", 251 "//base/security/permission_lite/services/pms_client:pms_client", 252 "//base/startup/init/interfaces/innerkits:libbegetutil", 253 "//build/lite/config/component/cJSON:cjson_shared", 254 "//foundation/communication/ipc/interfaces/innerkits/c/ipc:ipc_single", 255 "//foundation/systemabilitymgr/samgr_lite/samgr:samgr", 256 ] 257``` 258 259以上deps中的引用其他部件的内容使用了绝对路径是错误的(build仓忽略),建议修改为: 260 261```c 262 deps = [ 263 "${appexecfwk_lite_path}/frameworks/bundle_lite:bundle", 264 "//build/lite/config/component/cJSON:cjson_shared", 265 ] 266 267 external_deps = [ 268 "hilog_lite:hilog_shared", 269 "permission_lite:pms_client", 270 "init:libbegetutil", 271 "ipc:ipc_single", 272 "samgr_lite:samgr", 273 ] 274``` 275 276### 规则3.2 部件编译目标必须指定部件和子系统名。 277 278部件的编译单元ohos_shared_library、ohos_static_library、ohos_executable_library、ohos_source_set都必须指定“part_name”和“subsystem_name”。 279 280 281#### 修改建议: 282 283例如base/account/os_account/services/accountmgr/src/appaccount/BUILD.gn中 284 285```c 286ohos_shared_library("app_account_service_core") { 287 sources = [ 288 "app_account_event_proxy.cpp", 289 "app_account_stub.cpp", 290 ] 291 292 defines = [ 293 "ACCOUNT_LOG_TAG = \"AppAccountService\"", 294 "LOG_DOMAIN = 0xD001B00", 295 ] 296 297 configs = [ 298 ":app_account_service_core_config", 299 "${account_coverage_config_path}:coverage_flags", 300 ] 301 302 public_configs = [ ":app_account_service_core_public_config" ] 303 304 deps = [ "${app_account_innerkits_native_path}:app_account_innerkits" ] 305 306 external_deps = [ 307 "ability_base:want", 308 "c_utils:utils", 309 "hiviewdfx_hilog_native:libhilog", 310 "ipc:ipc_core", 311 ] 312 313 subsystem_name = "account" //原本没有,应该添加的内容! 314 part_name = "os_account" 315} 316``` 317 318 319### 规则4.1 部件编译脚本中禁止使用产品名称变量。 320 321部件是通用的系统能力,与特定产品无关。编译脚本中使用产品名称,将导致部件功能与产品绑定,不具备通用性。部件不同产品形态上的差异应抽象为特性或者运行时的插件。 322 323**例外:** vendor和device目录下三方厂商部件的编译脚本例外。 324 325 326#### 修改建议: 327例如: 328 329```c 330 if(product_name =="rk3568"){ //Bad,根据产品形态定义宏 331 defines += ["NON_SEPERATE_P2P] 332 } 333``` 334 335以上编译脚本中存在产品名称"rk3568"是不合理的,建议修改为: 336 337```c 338 declares_args(){ //将产品差异抽象为部件特性开关 339 wifi_non_seperate_p2p = true 340 } 341 342 if(wifi_non_seperate_p2p){ // 根据开关特性定义宏,而不是跟固定产品绑定 343 defines += ["NON_SEPERATE_P2P] 344 } 345``` 346 347## OpenHarmony部件编译构建规范白名单仓库 348 349OpenHarmony部件编译构建规范存在白名单仓库(仅对部件编译脚本生效(.gn .gni文件)),这些源码仓或代码目录不在检查范围内,具体如下: 350 3511. [manifest](https://gitee.com/openharmony/manifest/blob/master/ohos/ohos.xml) 文件中group字段标记为 ohos:mini 或 ohos:small的源码仓或代码目录。 3522. device、vendor开头的三方厂商源码仓。 3533. build仓。 3544. 全部third_party仓。 355 356## OpenHarmony部件编译构建规范门禁拦截逃生通道 357 358OpenHarmony部件编译构建规范门禁拦截结果会在format check中体现出来,请按照指导修改,如有特殊情况需要屏蔽,须特定人员评论component-static-check-ignore屏蔽。 359