• 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#其他常用模板
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.gni39
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.gni220
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