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