1# 模块 2## 模块配置规则 3 4编译子系统通过模块、部件和产品三层配置来实现编译和打包。模块就是编译子系统的一个目标,包括(动态库、静态库、配置文件、预编译模块等)。模块要定义属于哪个部件,一个模块只能归属于一个部件。OpenHarmony使用定制化的Gn模板来配置模块规则,Gn语法相关的基础知识请参考[官网手册](https://gn.googlesource.com/gn/+/main/docs/reference.md)。 5 6以下是常用的模块配置规则: 7 8``` 9# C/C++模板 10ohos_shared_library 11ohos_static_library 12ohos_executable 13ohos_source_set 14 15# 预编译模板: 16ohos_prebuilt_executable 17ohos_prebuilt_shared_library 18ohos_prebuilt_static_library 19 20#hap模板 21ohos_hap 22ohos_app_scope 23ohos_js_assets 24ohos_resources 25 26#其他常用模板 27#配置文件 28ohos_prebuilt_etc 29 30#sa配置 31ohos_sa_profile 32``` 33 34ohos开头的模板与内建模板的差异主要在于:推荐使用ohos定制模板。 35 36### C/C++模板示例 37 38ohos开头的模板对应的.gni文件路径在:openharmony/build/templates/cxx/cxx.gni。 39 40ohos_shared_library示例 41 42```shell 43import("//build/ohos.gni") 44ohos_shared_library("helloworld") { 45 sources = ["file"] 46 include_dirs = [] # 如有重复头文件定义,优先使用前面路径头文件 47 cflags = [] # 如重复冲突定义,后面的参数优先生效,也就是该配置项中优先生效 48 cflags_c = [] 49 cflags_cc = [] 50 ldflags = [] # 如重复冲突定义,前面参数优先生效,也就是ohos_template中预制参数优先生效 51 configs = [] 52 deps = [] # 部件内模块依赖 53 54 external_deps = [ # 跨部件模块依赖定义, 55 "part_name:module_name", # 定义格式为 "部件名:模块名称" 56 ] # 这里依赖的模块必须是依赖的部件声明在inner_kits中的模块 57 58 output_name = [string] # 模块输出名 59 output_extension = [] # 模块名后缀 60 module_install_dir = [] # 缺省在/system/lib64或/system/lib下, 模块安装路径,模块安装路径,从system/,vendor/后开始指定 61 relative_install_dir = [] # 模块安装相对路径,相对于/system/lib64或/system/lib;如果有module_install_dir配置时,该配置不生效 62 63 part_name = [string] # 必选,所属部件名称 64 output_dir 65 66 # Sanitizer配置,每项都是可选的,默认为false/空 67 sanitize = { 68 # 各个Sanitizer开关 69 cfi = [boolean] 70 integer_overflow = [boolean] 71 ... 72 73 debug = [boolean] # 调测模式 74 blocklist = [string] # 屏蔽名单路径 75 } 76 77 testonly = [boolean] 78 license_as_sources = [] 79 license_file = [] # 后缀名是.txt的文件 80 remove_configs = [] 81 no_default_deps = [] 82 install_images = [] 83 install_enable = [boolean] 84 symlink_target_name = [] 85 version_script = [] 86 use_exceptions = [] 87} 88``` 89 90ohos_static_library示例 91 92```shell 93import("//build/ohos.gni") 94ohos_static_library("helloworld") { 95 sources = ["file"] # 后缀名是.c的相关文件 96 include_dirs = ["dir"] # 包含目录 97 configs = [] # 配置 98 deps = [] # 部件内模块依赖 99 part_name = [string] # 部件名称 100 subsystem_name = [string] # 子系统名称 101 cflags = [] 102 103 external_deps = [ # 跨部件模块依赖定义, 104 "part_name:module_name", # 定义格式为 "部件名:模块名称" 105 ] # 这里依赖的模块必须是依赖的部件声明在inner_kits中的模块 106 107 lib_dirs = [] 108 public_configs = [] 109 110 # Sanitizer配置,每项都是可选的,默认为false/空 111 sanitize = { 112 # 各个Sanitizer开关 113 cfi = [boolean] 114 integer_overflow = [boolean] 115 ... 116 117 debug = [boolean] # 调测模式 118 blocklist = [string] # 屏蔽名单路径 119 } 120 121 remove_configs = [] 122 no_default_deps = [] 123 license_file = [] # 后缀名是.txt的文件 124 license_as_sources = [] 125 use_exceptions = [] 126} 127``` 128 129ohos_executable示例 130 131```shell 132import("//build/ohos.gni") 133ohos_executable("helloworld") { 134 configs = [] # 配置 135 part_name = [string] # 部件名称 136 subsystem_name = [string] # 子系统名称 137 deps = [] # 部件内模块依赖 138 139 external_deps = [ # 跨部件模块依赖定义, 140 "part_name:module_name", # 定义格式为 "部件名:模块名称" 141 ] # 这里依赖的模块必须是依赖的部件声明在inner_kits中的模块 142 ohos_test = [] 143 test_output_dir = [] 144 145 # Sanitizer配置,每项都是可选的,默认为false/空 146 sanitize = { 147 # 各个Sanitizer开关 148 cfi = [boolean] 149 integer_overflow = [boolean] 150 ... 151 152 debug = [boolean] # 调测模式 153 blocklist = [string] # 屏蔽名单路径 154 } 155 156 testonly = [boolean] 157 license_as_sources = [] 158 license_file = [] # 后缀名是.txt的文件 159 remove_configs = [] 160 static_link = [] 161 install_images = [] 162 module_install_dir = [] # 模块安装路径,从system/,vendor/后开始指定 163 relative_install_dir = [] 164 symlink_target_name = [] 165 output_dir = [directory] # 存放输出文件的目录 166 install_enable = [boolean] 167 version_script = [] 168 use_exceptions = [] 169} 170``` 171 172ohos_source_set示例 173 174```shell 175import("//build/ohos.gni") 176ohos_source_set("helloworld") { 177 sources = ["file"] # 后缀名是.c的相关文件 178 include_dirs = [] # 包含目录 179 configs = [] # 配置 180 public = [] # .h类型头文件 181 defines = [] 182 public_configs = [] 183 part_name = [string] # 部件名称 184 subsystem_name = [string] # 子系统名称 185 deps = [] # 部件内模块依赖 186 187 external_deps = [ # 跨部件模块依赖定义, 188 "part_name:module_name", # 定义格式为 "部件名:模块名称" 189 ] # 这里依赖的模块必须是依赖的部件声明在inner_kits中的模块 190 191 # Sanitizer配置,每项都是可选的,默认为false/空 192 sanitize = { 193 # 各个Sanitizer开关 194 cfi = [boolean] 195 integer_overflow = [boolean] 196 ... 197 198 debug = [boolean] # 调测模式 199 blocklist = [string] # 屏蔽名单路径 200 } 201 202 testonly = [boolean] 203 license_as_sources = [] 204 license_file = [] 205 remove_configs = [] 206 no_default_deps = [] 207 license_file = [] # 后缀名是.txt的文件 208 license_as_sources = [] 209 use_exceptions = [] 210} 211``` 212 213![icon-note.gif](public_sys-resources/icon-note.gif)**注意**: 214 - 只有sources和part_name是必选,其他都是可选的; 215 - Sanitizer配置详见:[Sanitizer使用说明](subsys-build-reference.md#Sanitizer使用说明) 216 217### 预编译模板示例 218 219预编译模板的.gni相关文件路径在:openharmony/build/templates/cxx/prebuilt.gni。 220 221ohos_prebuilt_executable示例 222 223```shell 224import("//build/ohos.gni") 225ohos_prebuilt_executable("helloworld") { 226 sources = ["file"] # 源 227 output = [] 228 install_enable = [boolean] 229 230 deps = [] # 部件内模块依赖 231 public_configs = [] 232 subsystem_name = [string] # 子系统名 233 part_name = [string] # 部件名 234 235 testonly = [boolean] 236 visibility = [] 237 238 install_images = [] 239 module_install_dir = [] # 模块安装路径,从system/,vendor/后开始指定 240 relative_install_dir = [] # 模块安装相对路径,相对于system/etc;如果有module_install_dir配置时,该配置不生效 241 symlink_target_name = [] 242 243 244 license_file = [] # 后缀名是.txt的文件 245 license_as_sources = [] 246} 247``` 248 249ohos_prebuilt_shared_library示例 250 251```shell 252import("//build/ohos.gni") 253ohos_prebuilt_shared_library("helloworld") { 254 sources = ["file"] # 一般是后缀为.so的文件 255 output = [] 256 install_enable = [boolean] 257 258 deps = [] # 部件内模块依赖 259 public_configs = [] 260 subsystem_name = [string] # 子系统名 261 part_name = [string] # 部件名 262 263 testonly = [boolean] 264 visibility = [] 265 266 install_images = [] 267 module_install_dir = [] # 模块安装路径,从system/,vendor/后开始指定 268 relative_install_dir = [] # 模块安装相对路径,相对于system/etc;如果有module_install_dir配置时,该配置不生效 269 symlink_target_name = [string] 270 271 272 license_file = [string] # 后缀名是.txt的文件 273 license_as_sources = [] 274} 275``` 276 277ohos_prebuilt_static_library示例 278 279```shell 280import("//build/ohos.gni") 281ohos_prebuilt_static_library("helloworld") { 282 sources = ["file"] # 一般是后缀为.so的文件 283 output = [] 284 285 deps = [] # 部件内模块依赖 286 public_configs = [] 287 subsystem_name = [string] # 子系统名 288 part_name = [string] # 部件名 289 290 testonly = [boolean] 291 visibility = [] 292 293 license_file = [string] # 后缀名是.txt的文件 294 license_as_sources = [] 295} 296``` 297 298![icon-note.gif](public_sys-resources/icon-note.gif)**注意**:只有sources和part_name是必选,其他都是可选的。 299 300### Hap模板 301 302hap模板详见:[ HAP编译构建指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/subsystems/subsys-build-gn-hap-compilation-guide.md) 303 304 305 306### 其他常用模板 307 308ohos_prebuilt_etc示例: 309 310```shell 311import("//build/ohos.gni") 312ohos_prebuilt_etc("helloworld") { 313 # ohos_prebuilt_etc模板最常用属性: 314 sources = ["file"] 315 module_install_dir = [] # 模块安装路径,从system/,vendor/后开始指定 316 subsystem_name = [string] # 子系统名 317 part_name = [string] # 必选,所属部件名称 318 install_images = [] 319 relative_install_dir = [] # 模块安装相对路径,相对于system/etc;如果有module_install_dir配置时,该配置不生效 320 321 # ohos_prebuilt_etc模板不常用属性: 322 deps = [] # 部件内模块依赖 323 testonly = [boolean] 324 visibility = [] 325 public_configs = [] 326 symlink_target_name = [string] 327 license_file = [string] 328 license_as_sources = [] 329} 330``` 331 332ohos_sa_profile示例: 333 334```shell 335import("//build/ohos.gni") 336ohos_sa_profile("helloworld") { 337 sources = [".xml"] # xml文件 338 part_name = [string] # 部件名 339 subsystem_name = [string] # 子系统名 340} 341``` 342 343![icon-note.gif](public_sys-resources/icon-note.gif)**注意**:只有sources和part_name是必选,其他都是可选的。 344 345## 新增并编译模块 346 347新建模块可以分为以下三种情况。主要的添加逻辑如下面的流程图所示,若没有子系统则需新建子系统并在该子系统的部件下添加模块,若没有部件则需新建部件并在其中添加模块,否则直接在原有部件中添加模块即可,需要注意的是芯片解决方案作为特殊部件是没有对应子系统的。 348 349- 在原有部件中添加一个模块 350 351- 新建部件并在其中添加模块 352 353- 新建子系统并在该子系统的部件下添加模块 354 355 ![模块添加流程](figures/module_addition_process.png) 356 357**在原有部件中添加一个模块** 358 3591. 在模块目录下配置BUILD.gn,根据模板类型选择对应的gn模板。 360 3612. 修改bundle.json配置文件。 362 363 ```shell 364 { 365 "name": "@ohos/<component_name>", # HPM部件英文名称,格式"@组织/部件名称" 366 "description": "xxxxxxxxxxxxxxxxxxx", # 部件功能一句话描述 367 "version": "3.1", # 版本号,版本号与OpenHarmony版本号一致 368 "license": "MIT", # 部件License 369 "publishAs": "code-segment", # HPM包的发布方式,当前默认都为code-segment 370 "segment": { 371 "destPath": "third_party/nghttp2" 372 }, # 发布类型为code-segment时为必填项,定义发布类型code-segment的代码还原路径(源码路径) 373 "dirs": {}, # HPM包的目录结构,字段必填内容可以留空 374 "scripts": {}, # HPM包定义需要执行的脚本,字段必填,值非必填 375 "licensePath": "COPYING", 376 "readmePath": { 377 "en": "README.rst" 378 }, 379 "component": { # 部件属性 380 "name": "<component_name>", # 部件名称 381 "subsystem": , # 部件所属子系统 382 "syscap": [], # 部件为应用提供的系统能力 383 "features": [], # 部件对外的可配置特性列表,一般与build中的sub_component对应,可供产品配置 384 "adapted_system_type": [], # 轻量(mini)小型(small)和标准(standard),可以是多个 385 "rom": "xxxKB" # ROM基线,没有基线写当前值 386 "ram": "xxxKB", # RAM基线,没有基线写当前值 387 "deps": { 388 "components": [], # 部件依赖的其他部件 389 "third_party": [] # 部件依赖的三方开源软件 390 }, 391 392 "build": { # 编译相关配置 393 "sub_component": [ 394 "//foundation/arkui/napi:napi_packages", # 原有模块1 395 "//foundation/arkui/napi:napi_packages_ndk" # 原有模块2 396 "//foundation/arkui/napi:new" # 新增模块new 397 ], # 部件编译入口,模块在此处配置 398 "inner_kits": [], # 部件间接口 399 "test": [] # 部件测试用例编译入口 400 } 401 } 402 } 403 ``` 404 405 ![icon-note.gif](public_sys-resources/icon-note.gif)**注意**:无论哪种方式该bundle.json文件均在对应子系统所在文件夹下。 406 4073. 成功添加验证:编译完成后打包到image中去,生成对应的so文件或者二进制文件。 408 409**新建部件并在其中添加一个模块** 410 4111. 在模块目录下配置BUILD.gn,根据模板类型选择对应的gn模板。这一步与在原有部件中添加一个模块的方法基本一致,只需注意该模块对应BUILD.gn文件中的part_name为新建部件的名称即可。 412 4132. 新建一个bundle.json文件,bundle.json文件均在对应子系统所在文件夹下。 414 4153. 在vendor/{product_company}/{product-name}/config.json中添加对应的部件,直接添加到原有部件后即可。 416 417 ```shell 418 "subsystems": [ 419 { 420 "subsystem": "部件所属子系统名", 421 "components": [ 422 { "component": "部件名1", "features":[] }, # 子系统下的原有部件1 423 { "component": "部件名2", "features":[] }, # 子系统下的原有部件2 424 { "component": "部件名new", "features":[] } # 子系统下的新增部件new 425 ] 426 }, 427 . 428 ] 429 ``` 430 4314. 成功添加验证:编译完成后打包到image中去,生成对应的so文件或者二进制文件。 432 433 434**新建子系统并在该子系统的部件下添加模块** 435 4361. 在模块目录下配置BUILD.gn,根据模板类型选择对应的gn模板。这一步与新建部件并在其中添加模块中对应的步骤并无区别。 437 4382. 在新建的子系统目录下每个部件对应的文件夹下创建bundle.json文件,定义部件信息。这一步与新建部件并在其中添加模块中对应的步骤并无区别。 439 4403. 修改build目录下的subsystem_config.json文件。 441 442 ```shell 443 { 444 "子系统名1": { # 原有子系统1 445 "path": "子系统目录1", 446 "name": "子系统名1" 447 }, 448 "子系统名2": { # 原有子系统2 449 "path": "子系统目录2", 450 "name": "子系统名2" 451 }, 452 "子系统名new": { # 新增子系统new 453 "path": "子系统目录new", 454 "name": "子系统名new" 455 }, 456 457 } 458 ``` 459 460 该文件定义了有哪些子系统以及这些子系统所在文件夹路径,添加子系统时需要说明子系统path与name,分别表示子系统路径和子系统名。 461 4624. 在vendor/{product_company}/{product-name}目录下的产品配置如product-name是hispark_taurus_standard时,在config.json中添加对应的部件,直接添加到原有部件后即可。 463 464 ```shell 465 "subsystems": [ 466 { 467 "subsystem": "arkui", # 原有的子系统名 468 "components": [ # 单个子系统下的所有部件集合 469 { 470 "component": "ace_engine_standard", # 原有的部件名 471 "features": [] 472 }, 473 { 474 "component": "napi", # 原有的部件名 475 "features": [] 476 } 477 { 478 "component": "component_new1", # 原有子系统新增的的部件名component_new1 479 "features": [] 480 } 481 ] 482 }, 483 { 484 "subsystem": "subsystem_new", # 新增的子系统名 485 "components": [ 486 { 487 "component": "component_new2", # 新增子系统新增的的部件名component_new2 488 "features": [] 489 } 490 ] 491 }, 492 493 ] 494 ``` 495 4964. 成功添加验证:编译完成后打包到image中去,生成对应的so文件或者二进制文件。 497 498 499**编译模块** 500 501主要有两种编译方式,[命令行方式和hb方式](subsys-build-all.md#编译命令),这里以命令行方式为例。 502 503 模块可以使用“--build-target 模块名"单独编译,编译命令如下: 504 505 ```shell 506 ./build.sh --build-target 模块名 507 ``` 508 509 也可以编译相应产品,以编译hispark_taurus_standard为例,编译命令如下: 510 511 ```shell 512 ./build.sh --product-name hispark_taurus_standard --build-target 模块名 --ccache 513 ``` 514 515 还可以编译模块所在的部件: 516 517 ```shell 518 ./build.sh --product-name hispark_taurus_standard --build-target musl --build-target 模块名 --ccache 519 ``` 520