readme.md
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