• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Building Guidelines for Mini and Small Systems<a name="EN-US_TOPIC_0000001060646620"></a>
2
3-   [Overview](#section10958256161119)
4    -   [Basic Concepts](#section1732301411128)
5    -   [Directory Structure](#section1588744014121)
6    -   [Build Process](#section15761735134)
7
8-   [Configuration Rules](#section2345183962710)
9    -   [Module](#section142532518308)
10    -   [Chipset](#section121501451143710)
11    -   [Product](#section134549283435)
12
13-   [Usage Guidelines](#section13754457192211)
14    -   [Prerequisites](#section31651120233)
15    -   [Using hb](#section1133304172313)
16    -   [Adding a Module](#section167110415315)
17    -   [Adding a Chipset Solution](#section1474718565412)
18    -   [Adding a Product Solution](#section1097623294220)
19
20-   [Troubleshooting](#section19909721104319)
21    -   [Invalid -- w Option](#section138233464318)
22    -   [Library ncurses Not Found](#section151033911442)
23    -   [mcopy not Found](#section19811838104418)
24    -   [No riscv File or Directory](#section03111118451)
25    -   [No Crypto](#section69981127125013)
26    -   [Unexpected Operator](#section967617530505)
27
28
29## Overview<a name="section10958256161119"></a>
30
31The Compilation and Building subsystem is a build framework that supports module-based OpenHarmony development using Generate Ninja \(GN\) and Ninja. You can use this subsystem to:
32
33-   Assemble modules for a product and build the product.
34
35-   Build chipset source code independently.
36-   Build a single module independently.
37
38### Basic Concepts<a name="section1732301411128"></a>
39
40Learn the following concepts before you start compilation and building:
41
42-   Subsystem
43
44    A subsystem is a logical concept. It consists of one or more modules. OpenHarmony is designed with a layered architecture, which consists of the kernel layer, system service layer, framework layer, and application layer from bottom to top. System functions are developed by the level of system, subsystem, and module. In a multi-device deployment scenario, you can customize subsystems and modules as required.
45
46
47-   Module
48
49    A module is a reusable, configurable, and tailorable function unit. Each module has an independent directory, and multiple modules can be developed concurrently and built and tested independently.
50
51-   **GN**
52
53    Generate Ninja \(GN\) is used to generate Ninja files.
54
55-   **Ninja**
56
57    Ninja is a small high-speed build system.
58
59-   **hb**
60
61    hb is a command line tool for OpenHarmony to execute build commands.
62
63
64### Directory Structure<a name="section1588744014121"></a>
65
66```
67build/lite
68├── components                  # Module description file
69├── figures                     # Figures in the readme file
70├── hb                          # hb pip installation package
71├── make_rootfs                 # Script used to create the file system image
72├── config                      # Build configuration
73│   ├── component               # Module-related template definition
74│   ├── kernel                  # Kernel-related build configuration
75│   └── subsystem               # Subsystem build configuration
76├── platform                    # ld script
77├── testfwk                     # Test build framework
78└── toolchain                   # Build toolchain configuration, which contains the compiler directories, build options, and linking options
79```
80
81### **Build Process**<a name="section15761735134"></a>
82
83[Figure 1](#fig9744112715161)  shows the build process.
84
85**Figure  1**  Build process<a name="fig9744112715161"></a>
86![](figure/build-process.jpg "build-process")
87
881.  Use  **hb set **to set the OpenHarmony source code directory and the product to build.
892.  Use  **hb build**  to build the product, development board, or module. The procedure is as follows:
90    -   Read the  **config.gni**  file of the development board selected. The file contains the build toolchain, linking commands, and build options.
91    -   Run the  **gn gen**  command to read the product configuration and generate the  **out**  directory and  **ninja**  files for the solution.
92    -   Run  **ninja -C out/board/product**  to start the build.
93    -   Package the build result, set the file attributes and permissions, and create a file system image.
94
95
96## Configuration Rules<a name="section2345183962710"></a>
97
98To ensure that the chipset and product solutions are pluggable and decoupled from OpenHarmony, the paths, directory trees, and configuration of modules, chipset solutions, and product solutions must comply with the following rules:
99
100### **Module**<a name="section142532518308"></a>
101
102The source code directory for a module is named in the  _\{Domain\}/\{Subsystem\}/\{Module\}_  format. The module directory tree is as follows:
103
104>![](../public_sys-resources/icon-caution.gif) **CAUTION:**
105>Define module attributes, such as the name, source code directory, function description, mandatory or not, build targets, RAM, ROM, build outputs, adapted kernels, configurable features, and dependencies, in the JSON file of the subsystem in the  **build/lite/components**  directory. When adding a module, add its definition to the JSON file of the corresponding subsystem. The module configured for a product must have been defined in a subsystem. Otherwise, the verification will fail.
106
107```
108component
109├── interfaces
110│   ├── innerkits  # APIs exposed internally among modules
111│   └── kits       # App APIs provided for app developers
112├── frameworks     # Framework implementation
113├── services       # Service implementation
114└── BUILD.gn       # Build script
115```
116
117The following example shows how to define attributes of the sensor module of the pan-sensor subsystem:
118
119```
120{
121  "components": [
122    {
123      "component": "sensor_lite",                # Module name
124      "description": "Sensor services",          # Brief description of the module
125      "optional": "true",                        # Whether the module is mandatory for the system
126      "dirs": [                                  # Source code directory of the module
127        "base/sensors/sensor_lite"
128      ],
129      "targets": [                               # Build entry of the module
130        "//base/sensors/sensor_lite/services:sensor_service"
131      ],
132      "rom": "92KB",                             # Module ROM
133      "ram": "~200KB",                           # Module RAM (estimated)
134      "output": [ "libsensor_frameworks.so" ],   # Module build outputs
135      "adapted_kernel": [ "liteos_a" ],          # Adapted kernel for the module
136      "features": [],                            # Configurable features of the module
137      "deps": {
138        "components": [                          # Other modules on which the module depends
139          "samgr_lite",
140          "ipc_lite"
141
142        ],
143        "third_party": [                         # Open-source third-party software on which the module depends
144          "bounds_checking_function"
145        ]
146      }
147    }
148  ]
149}
150```
151
152Observe the following rules when building the  **BUILD.gn**  module:
153
154-   The build target name must be the same as the module name.
155-   Define the configurable features in the  **BUILD.gn**  file of the module. Name the configurable features in the  **ohos\_**\{_subsystem_\}**\_**\{_module_\}**\_**\{_feature_\} format. Define the features in module description and configure them in the  **config.json**  file.
156-   Define macros in the  **OHOS\_**\{_SUBSYSTEM_\}**\_**\{_MODULE_\}**\_**\{_FEATURE_\} format.
157
158    >![](../public_sys-resources/icon-note.gif) **NOTE:**
159    >GN is used as the build script language for modules. For details about how to use GN, see the  [GN Quick Start Guide](https://gn.googlesource.com/gn/+/master/docs/quick_start.md). In GN, a module is a build target, which can be a static library, a dynamic library, an executable file, or a group.
160
161
162The following example shows how to build the  **foundation/graphic/ui/BUILD.gn**  file for a graphics UI module:
163
164```
165	# Declare the configurable features of the module
166	declare_args() {
167  enable_ohos_graphic_ui_animator = false # Animation switch
168  ohos_ohos_graphic_ui_font = "vector"    # Configurable font type, which can be vector or bitmap
169	}
170
171	# Basic module functions
172	shared_library("base") {
173	  sources = [
174	    ......
175	  ]
176	  include_dirs = [
177	    ......
178	  ]
179	}
180
181	# Build only when the animator is enabled
182	if(enable_ohos_graphic_ui_animator ) {
183	  shared_library("animator") {
184	    sources = [
185	      ......
186	    ]
187	    include_dirs = [
188              ......
189	    ]
190	    deps = [ :base ]
191	  }
192	}
193	......
194	# It is recommended that the target name be the same as the module name, which can be an executable .bin file, shared_library (.so file), static_library (.a file), or a group.
195	executable("ui") {
196	  deps = [
197	    ":base"
198	  ]
199
200	  # The animator feature is configured by the product.
201	  if(enable_ohos_graphic_ui_animator ) {
202	      deps += [
203	        "animator"
204	      ]
205	  }
206	}
207```
208
209### **Chipset**<a name="section121501451143710"></a>
210
211-   The chipset solution is a complete solution based on a development board. The solution includes the drivers, API adaptation, and SDK.
212-   The chipset solution is a special module, whose source code directory is named in the  _**device**/\{Chipset solution vendor\}/\{Development board\}_  format.
213-   The chipset solution module is built by default based on the development board selected by the product.
214
215The chipset solution directory tree is as follows:
216
217```
218device
219└── company                         # Chipset solution vendor
220    └── board                       # Name of the development board
221        ├── BUILD.gn                # Build script
222        ├── hals                    # Southbound APIs for OS adaptation
223        ├── linux                   # Linux kernel version (optional)
224        │   └── config.gni          # Build options for the Linux version
225        └── liteos_a                # LiteOS kernel version (optional)
226            └── config.gni          # Build options for the LiteOS Cortex-A version
227```
228
229>![](../public_sys-resources/icon-note.gif) **NOTE:**
230>The  **config.gni**  file contains build-related configurations of the development board. The parameters in the file are globally visible to the system and can be used to build all OS modules during the build process.
231
232The  **config.gni**  file contains the following key parameters:
233
234```
235kernel_type:            kernel used by the development board, for example, liteos_a, liteos_m, or linux.
236kernel_version:         kernel version used by the development board, for example, 4.19.
237board_cpu:              CPU of the development board, for example, cortex-a7 or riscv32.
238board_arch:             chipset architecture of the development board, for example, armv7-a or rv32imac.
239board_toolchain:        name of the customized build toolchain used by the development board, for example, gcc-arm-none-eabi. If this field is not specified, ohos-clang will be used by default.
240board_toolchain_prefix: prefix of the build toolchain, for example, gcc-arm-none-eabi.
241board_toolchain_type:  build toolchain type, for example, gcc or clang. Currently, only GCC and clang are supported.
242board_cflags:          build options of the .c file configured for the development board.
243board_cxx_flags:       build options of the .cpp file configured for the development board.
244board_ld_flags:        link options configured for the development board.
245```
246
247### **Product**<a name="section134549283435"></a>
248
249The product solution is a complete product based on a development board. It includes the OS adaptation, module assembly configuration, startup configuration, and file system configuration. The source code directory of a product solution is named in the  **vendor**/\{_Product solution vendor_\}/\{_Product name_\} format. A product solution is also a special module.
250
251The product solution directory tree is as follows:
252
253```
254vendor
255└── company                         # Product solution vendor
256    ├── product                     # Product name
257    │   ├── init_configs
258    │   │     ├── etc               # Startup configuration of the init process (only required for the Linux kernel)
259    │   │     └── init.cfg          # System service startup configuration
260    │   ├── hals                    # OS adaptation
261    │   ├── BUILD.gn                # Product build script
262    │   └── config.json             # Product configuration file
263    │   └── fs.yml                  # File system packaging configuration
264    └── ......
265```
266
267>![](../public_sys-resources/icon-caution.gif) **CAUTION:**
268>Create directories and files based on the preceding rules for new products. The Compilation and Building subsystem scans the configured products based on the rules.
269
270The key directories and files are described as follows:
271
2721.  **vendor/company/product/init\_configs/etc**
273
274    This folder contains the  **rcS**,  **S**_xxx_, and  **fstab**  scripts. The  **init**  process runs the  **rcS**,  **fstab**, and  **S**_00_-_xxx_  scripts in sequence before starting system services. The  **S**_xxx_  script contains content related to the development board and product. It is used to create device nodes and directories, scan device nodes, and change file permissions. These scripts are copied from the  **BUILD.gn**  file to the  **out**  directory of the product as required and packaged into the  **rootfs**  image.
275
2762.  **vendor/company/product/init\_configs/init.cfg**
277
278    This file is the configuration file for the  **init**  process to start services. Currently, the following commands are supported:
279
280    -   **start**: starts a service.
281    -   **mkdir**: creates a folder.
282    -   **chmod**: changes the permission on a specified directory or file.
283    -   **chown**: changes the owner group of a specified directory or file.
284    -   **mount**: mounts a device.
285
286    The fields in the file are described as follows:
287
288    ```
289    {
290        "jobs" : [{                                                     # Job array. A job corresponds to a command set. Jobs are executed in the following sequence: pre-init > init > post-init.
291                "name" : "pre-init",
292                "cmds" : [
293                    "mkdir /storage/data",                              # Create a directory.
294                    "chmod 0755 /storage/data",                         # Change the permission, which is in 0xxx format, for example, 0755.
295                    "mkdir /storage/data/log",
296                    "chmod 0755 /storage/data/log",
297                    "chown 4 4 /storage/data/log",                      # Change the owner group. The first number indicates the UID, and the second indicates the GID.
298                    ......
299                    "mount vfat /dev/mmcblock0 /sdcard rw, umask=000"    # The command is in the mount [File system type][source] [target] [flags] [data] format.
300                                                                        # Currently, flags can only be nodev, noexec, nosuid, or rdonly.
301                ]
302            }, {
303                "name" : "init",
304                "cmds" : [                                              # Start services based on the sequence of the cmds array.
305                    "start shell",                                      # Note that there is only one space between start and the service name.
306                    ......
307                    "start service1"
308                ]
309            }, {
310                "name" : "post-init",                                   # Job that is finally executed. Operations performed after the init process is started, for example, mounting a device after the driver initialization.
311                "cmds" : []
312            }
313        ],
314        "services" : [{                                                 # Service array. A service corresponds to a process.
315                "name" : "shell",                                       # Service name
316                "path" : ["/sbin/getty", "-n", "-l", "/bin/sh", "-L", "115200", "ttyS000", "vt100"],    # Full path of the executable file. It must start with "path".
317                "uid" : 0,                                              # Process UID, which must be the same as that in the binary file.
318                "gid" : 0,                                              # Process GID, which must be the same as that in the binary file.
319                "once" : 0,                                             # Whether the process is a one-off process. 1: The proces is a one-off process. The init process does not restart it after the process exits. 0: The process is not a one-off process. The init process restarts it if the process exits.
320                "importance" : 0,                                       # Whether the process is a key process. 1: The process is a key process. If it exits, the init process restarts the board. 0: The process is not a key process. If it exits, the init process does not restart the board.
321                "caps" : [4294967295]
322            },
323            ......
324        ]
325    }
326    ```
327
3283.  **vendor/company/product/init\_configs/hals**
329
330    This file stores the content related to OS adaptation of the product. For details about APIs for implementing OS adaptation, see the readme file of each module.
331
3324.  **vendor/company/product/config.json**
333
334    The  **config.json**  file is the main entry for the build and contains configurations of the development board, OS modules, and kernel.
335
336    The following example shows the  **config.json**  file of the IP camera developed based on the hispark\_taurus development board:
337
338    ```
339    {
340    	"product_name": "ipcamera",                       # Product name
341    	"ohos_version": "OpenHarmony 1.0",                # OS version
342    	"device_company": "hisilicon",                    # Chipset vendor
343    	"board": "hispark_taurus",                        # Name of the development board
344    	"kernel_type": "liteos_a",                        # Kernel type
345     	"kernel_version": "3.0.0",                        # Kernel version
346    	"subsystems": [
347    	  {
348        "subsystem": "aafwk",                         # Subsystem
349    	    "components": [
350          { "component": "ability", "features":[ "enable_ohos_appexecfwk_feature_ability = true" ] }   # Module and its features
351    	    ]
352    	  },
353    	  {
354    	   ......
355    	  }
356    	  ......
357      More subsystems and modules
358    	}
359    }
360    ```
361
3625.  **vendor/company/product/fs.yml**
363
364    This file packages the build result to create a configuration file system image, for example,  **rootfs.img**  \(user-space root file system\) and  **userfs.img**  \(readable and writable file\). It consists of multiple lists, and each list corresponds to a file system. The fields are described as follows:
365
366    ```
367    fs_dir_name: (Mandatory) declares the name of the file system, for example, rootfs or userfs.
368    fs_dirs:     (Optional) configures the mapping between the file directory in the out directory and the system file directory. Each file directory corresponds to a list.
369    source_dir:  (Optional) specifies the target file directory in the out directory. If this field is missing, an empty directory will be created in the file system based on target_dir.
370    target_dir:  (Mandatory) specifies the corresponding file directory in the file system.
371    ignore_files: (Optional) declares ignored files during the copy operation.
372    dir_mode:    (Optional) specifies the file directory permission, which is set to 755 by default.
373    file_mode: (Optional) declares permissions of all files in the directory, which is set to 555 by default.
374    fs_filemode: (Optional) configures files that require special permissions. Each file corresponds to a list.
375    file_dir:    (Mandatory) specifies the detailed file path in the file system.
376    file_mode:   (Mandatory) declares file permissions.
377    fs_symlink:  (Optional) configures the soft link of the file system.
378    fs_make_cmd: (Mandatory) creates the file system script. The script provided by the OS is stored in the build/lite/make_rootfs directory. Linux, LiteOS, ext4, jffs2, and vfat are supported. Chipset vendors can also customize the script as required.
379    fs_attr:     (Optional) dynamically adjusts the file system based on configuration items.
380    ```
381
382    The  **fs\_symlink**  and  **fs\_make\_cmd**  fields support the following variables:
383
384    -   $\{root\_path\}
385
386        Code root directory, which corresponds to  **$\{ohos\_root\_path\}**  of GN
387
388    -   $\{out\_path\}
389
390        **out**  directory of the product, which corresponds to  **$\{root\_out\_dir\}**  of GN
391
392    -   $\{fs\_dir\}
393
394        File system directory, which consists of the following variables
395
396        -   $\{root\_path\}
397        -   $\{fs\_dir\_name\}
398
399    >![](../public_sys-resources/icon-note.gif) **NOTE:**
400    >**fs.yml**  is optional and does not need to be configured for devices without a file system.
401
4026.  **vendor/company/product/BUILD.gn**
403
404    This file is the entry for building the source code of the solution vendor and copying the startup configuration file. The  **BUILD.gn**  file in the corresponding product directory will be built by default if a product is selected. The following example shows how to build the  **BUILD.gn**  file of a product:
405
406    ```
407    group("product") { # The target name must be the same as the product name (level-3 directory name under the product directory).
408      deps = []
409      # Copy the init configuration.
410      deps += [ "init_configs" ]
411      # Others
412      ......
413    }
414    ```
415
416
417## Usage Guidelines<a name="section13754457192211"></a>
418
419### Prerequisites<a name="section31651120233"></a>
420
421The development environment has GN, Ninja, Python 3.7.4 or later, and hb available. For details about installation methods, see  [Environment Setup](../quick-start/quickstart-lite-env-setup.md).
422
423### Using hb<a name="section1133304172313"></a>
424
425**hb**  is a command line tool for OpenHarmony to execute build commands. Common hb commands are described as follows:
426
427**hb set**
428
429```
430hb set -h
431usage: hb set [-h] [-root [ROOT_PATH]] [-p]
432
433optional arguments:
434  -h, --help            show this help message and exit
435  -root [ROOT_PATH], --root_path [ROOT_PATH]
436                        Set OHOS root path
437  -p, --product         Set OHOS board and kernel
438```
439
440-   **hb set**  \(without argument\): starts the default setting process.
441-   **hb set -root** _dir_: sets the root directory of the code.
442-   **hb set -p**: sets the product to build.
443
444**hb env**
445
446Displays the current configuration.
447
448```
449hb env
450[OHOS INFO] root path: xxx
451[OHOS INFO] board: hispark_taurus
452[OHOS INFO] kernel: liteos
453[OHOS INFO] product: ipcamera
454[OHOS INFO] product path: xxx/vendor/hisilicon/ipcamera
455[OHOS INFO] device path: xxx/device/hisilicon/hispark_taurus/sdk_linux_4.19
456```
457
458**hb build**
459
460```
461hb build -h
462usage: hb build [-h] [-b BUILD_TYPE] [-c COMPILER] [-t [TEST [TEST ...]]]
463                [--dmverity] [--tee] [-p PRODUCT] [-f] [-n]
464                [-T [TARGET [TARGET ...]]] [-v] [-shs] [--patch]
465                [component [component ...]]
466
467positional arguments:
468  component             name of the component
469
470optional arguments:
471  -h, --help            show this help message and exit
472  -b BUILD_TYPE, --build_type BUILD_TYPE
473                        release or debug version
474  -c COMPILER, --compiler COMPILER
475                        specify compiler
476  -t [TEST [TEST ...]], --test [TEST [TEST ...]]
477                        compile test suit
478  --dmverity            Enable dmverity
479  --tee                 Enable tee
480  -p PRODUCT, --product PRODUCT
481                        build a specified product with
482                        {product_name}@{company}, eg: camera@huawei
483  -f, --full            full code compilation
484  -n, --ndk             compile ndk
485  -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]]
486                        Compile single target
487  -v, --verbose         show all command lines while building
488  -shs, --sign_haps_by_server
489                        sign haps by server
490  --patch               apply product patch before compiling
491
492  --dmverity            Enable dmverity
493  -p PRODUCT, --product PRODUCT
494                        build a specified product with
495                        {product_name}@{company}, eg: ipcamera@hisilcon
496  -f, --full            full code compilation
497  -T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]]
498                        Compile single target
499```
500
501-   **hb build**  \(without argument\): builds the code based on the configured code directory, product, and options. The  **-f**  option deletes all products to be built, which is equivalent to running  **hb clean**  and  **hb build**.
502-   **hb build** _\{module\_name\}_: builds a product module separately based on the development board and kernel set for the product, for example,  **hb build kv\_store**.
503-   **hb build -p ipcamera@hisilicon**: skips the  **set**  step and builds the product directly.
504-   You can run  **hb build**  in  **device/device\_company/board**  to select the kernel and start the build based on the current development board and the selected kernel to generate an image that contains the kernel and driver only.
505
506**hb clean**
507
508You can run  **hb clean**  to clear the build result of the product in the  **out**  directory and retain the  **args.gn**  and  **build.log**  files only. To clear files in a specified directory, add the directory parameter to the command, for example,  **hb clean out/xxx/xxx**.
509
510```
511hb clean
512usage: hb clean [-h] [out_path]
513
514positional arguments:
515  out_path    clean a specified path.
516
517optional arguments:
518  -h, --help  show this help message and exit
519```
520
521### Adding a Module<a name="section167110415315"></a>
522
523To add a module, determine the subsystem to which the module belongs and the module name, and then perform the following steps:
524
5251.  Add the module build script after the source code development is complete.
526
527    The following example adds the  **BUILD.gn**  script \(stored in the  **applications/sample/hello\_world**  directory\) to build the  **hello\_world**  module \(as an executable file\).
528
529    ```
530    executable("hello_world") {
531      include_dirs = [
532        "include",
533       ]
534      sources = [
535        "src/hello_world.c"
536      ]
537    }
538    ```
539
540    The above script is used to build  **hello\_world**  that can run on OpenHarmony.
541
542    To build the preceding module separately, select a product via the  **hb set**  command and run the  **-T**  command.
543
544    ```
545    hb build -f -T //applications/sample/hello_world
546    ```
547
548    After the module functions are verified on the development board, perform steps  [2 to 4](#li11471037297)  to configure the module to the product.
549
5502.  <a name="li11471037297"></a>Add module description.
551
552    The module description is stored in the  **build/lite/components**  directory. New modules must be added to the JSON file of the corresponding subsystem. The module description must contain the following fields:
553
554    -   **module**: name of the module
555    -   **description**: brief description of the module
556    -   **optional**: whether the module is optional
557    -   **dirs**: source code directory of the module
558    -   **targets**: module build entry
559
560    For example, to add the  **hello\_world**  module to the application subsystem, add the  **hello\_world**  object to the  **applications.json**  file.
561
562    ```
563    {
564      "components": [
565        {
566          "component": "hello_world",
567          "description": "Hello world.",
568          "optional": "true",
569          "dirs": [
570            "applications/sample/hello_world"
571          ],
572          "targets": [
573            "//applications/sample/hello_world"
574          ]
575        },
576        ...
577       ]
578    }
579    ```
580
5813.  Configure the module for the product.
582
583    The  **config.json**  file is stored in the  **vendor/company/product/**  directory. The file must contain the product name, OpenHarmony version, device vendor, development board, kernel type, kernel version, and the subsystem and module to configure. The following example adds the  **hello\_world**  module to the  **my\_product.json**  configuration file:
584
585    ```
586    {
587        "product_name": "hello_world_test",
588        "ohos_version": "OpenHarmony 1.0",
589        "device_company": "hisilicon",
590        "board": "hispark_taurus",
591        "kernel_type": "liteos_a",
592        "kernel_version": "1.0.0",
593        "subsystems": [
594          {
595            "subsystem": "applications",
596            "components": [
597              { "component": "hello_world", "features":[] }
598            ]
599          },
600          ...
601        ]
602    }
603    ```
604
6054.  Build the product.
606
607    1. Run the  **hb set**  command in the root code directory and select the product.
608
609    2. Run the  **hb build**  command.
610
611
612### Adding a Chipset Solution<a name="section1474718565412"></a>
613
614The following uses the RTL8720 development board provided by Realtek as an example. To a chipset solution, perform the following steps:
615
6161.  <a name="li1970321162111"></a>Create a directory for the chipset solution.
617
618    To create a directory based on  [1-Configuration Rules for Modules, Chipset Solutions, and Product Solutions](#section1625463413327), run the following command in the root code directory:
619
620    ```
621    mkdir -p device/realtek/rtl8720
622    ```
623
6242.  Create a directory for kernel adaptation and build the  **config.gni**  file of the development board.
625
626    For example, to adapt the LiteOS-A kernel to the RTL8720 development board, configure the  **device/realtek/rtl8720/liteos\_a/config.gni**  file as follows:
627
628    ```
629    # Kernel type, e.g. "linux", "liteos_a", "liteos_m".
630    kernel_type = "liteos_a"
631
632    # Kernel version.
633    kernel_version = "3.0.0"
634
635    # Board CPU type, e.g. "cortex-a7", "riscv32".
636    board_cpu = "real-m300"
637
638    # Board arch, e.g. "armv7-a", "rv32imac".
639    board_arch = ""
640
641    # Toolchain name used for system compiling.
642    # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf.
643    # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain.
644    board_toolchain = "gcc-arm-none-eabi"
645
646    # The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc.
647    board_toolchain_path =
648        rebase_path("//prebuilts/gcc/linux-x86/arm/gcc-arm-none-eabi/bin",
649                    root_build_dir)
650
651    # Compiler prefix.
652    board_toolchain_prefix = "gcc-arm-none-eabi-"
653
654    # Compiler type, "gcc" or "clang".
655    board_toolchain_type = "gcc"
656
657    # Board related common compile flags.
658    board_cflags = []
659    board_cxx_flags = []
660    board_ld_flags = []
661    ```
662
6633.  Build the script.
664
665    Create the  **BUILD.gn**  file in the development board directory. The target name must be the same as that of the development board. The content in the  **device/realtek/rtl8720/BUILD.gn**  file is configured as follows:
666
667    ```
668    group("rtl8720") { # The target can be shared_library, static_library, or an executable file.
669      # Content
670      ......
671    }
672    ```
673
6744.  Build the chipset solution.
675
676    Run the  **hb build**  command in the development board directory to start the build.
677
678
679### Adding a Product Solution<a name="section1097623294220"></a>
680
681You can use the Compilation and Building subsystem to customize product solutions by assembling chipset solutions and modules. The procedure is as follows:
682
6831.  Create a product directory.
684
685    The following uses the Wi-Fi IoT module on the RTL8720 development board as an example. Run the following command in the root code directory to create a product directory based on  [1-Configuration Rules for Modules, Chipset Solutions, and Product Solutions](#section1625463413327):
686
687    ```
688    mkdir -p vendor/my_company/wifiiot
689    ```
690
6912.  Assemble the product.
692
693    Create the  **config.json**  file in the product directory. The  **vendor/my\_company/wifiiot/config.json**  file is as follows:
694
695    ```
696    {
697        "product_name": "wifiiot",                        # Product name
698        "ohos_version": "OpenHarmony 1.0",                # OS version
699        "device_company": "realtek",                      # Name of the chipset solution vendor
700        "board": "rtl8720",                               # Name of the development board
701        "kernel_type": "liteos_m",                        # Kernel type
702        "kernel_version": "3.0.0",                        # Kernel version
703        "subsystems": [
704          {
705            "subsystem": "kernel",                        # Subsystem
706            "components": [
707              { "component": "liteos_m", "features":[] }  # Module and its features
708            ]
709          },
710          ...
711          {
712             More subsystems and modules
713          }
714        ]
715    }
716    ```
717
718    Before the build, the Compilation and Building subsystem checks the validity of fields, including  **device\_company**,  **board**,  **kernel\_type**,  **kernel\_version**,  **subsystem**, and  **component**. The  **device\_company**,  **board**,  **kernel\_type**, and  **kernel\_version**  fields must match the current chipset solution, and  **subsystem**  and  **component**  must match the module description in the  **build/lite/components**  file.
719
7203.  Implement adaptation to OS APIs.
721
722    Create the  **hals**  directory in the product directory and store the source code as well as the build script for OS adaptation in this directory.
723
7244.  Configure the system service.
725
726    Create the  **init\_configs**  directory in the product directory and then the  **init.cfg**  file in the newly created directory. Configure the system service to be started.
727
7285.  \(Optional\) Configure the init process only for the Linux kernel.
729
730    Create the  **etc**  directory in the  **init\_configs**  directory, and then the  **init.d**  folder and the  **fstab**  file in the newly created directory. Then, create the  **rcS**  and  **S**_xxx_  files in the  **init.d**  file and edit them based on product requirements.
731
7326.  \(Optional\) Configure the file system image only for the development board that supports the file system.
733
734    Create the  **fs.yml**  file in the product directory and configure it as required. A typical  **fs.yml**  file is as follows:
735
736    ```
737    -
738      fs_dir_name: rootfs # Image name
739      fs_dirs:
740        -
741          # Copy the files in the out/my_board/my_product/bin directory to the rootfs/bin directory and ignore the .bin files related to testing.
742          source_dir: bin
743          target_dir: bin
744          ignore_files:
745            - Test.bin
746            - TestSuite.bin
747        -
748          # Copy the files in the out/my_board/my_product/libs directory to the rootfs/lib directory, ignore all .a files, and set the file permissions to 644 and folder permissions 755.
749          source_dir: libs
750          target_dir: lib
751          ignore_files:
752            - .a
753          dir_mode: 755
754          file_mode: 644
755        -
756          source_dir: usr/lib
757          target_dir: usr/lib
758          ignore_files:
759            - .a
760          dir_mode: 755
761          file_mode: 644
762        -
763          source_dir: config
764          target_dir: etc
765        -
766          source_dir: system
767          target_dir: system
768        -
769          source_dir: sbin
770          target_dir: sbin
771        -
772          source_dir: usr/bin
773          target_dir: usr/bin
774        -
775          source_dir: usr/sbin
776          target_dir: usr/sbin
777        -
778          # Create an empty proc directory.
779          target_dir: proc
780        -
781          target_dir: mnt
782        -
783          target_dir: opt
784        -
785          target_dir: tmp
786        -
787          target_dir: var
788        -
789          target_dir: sys
790        -
791          source_dir: etc
792          target_dir: etc
793        -
794          source_dir: vendor
795          target_dir: vendor
796        -
797          target_dir: storage
798
799      fs_filemode:
800        -
801          file_dir: lib/ld-uClibc-0.9.33.2.so
802          file_mode: 555
803        -
804          file_dir: lib/ld-2.24.so
805          file_mode: 555
806        -
807          file_dir: etc/init.cfg
808          file_mode: 400
809      fs_symlink:
810        -
811          # Create the soft link ld-musl-arm.so.1 -> libc.so in the rootfs/lib directory.
812          source: libc.so
813          link_name: ${fs_dir}/lib/ld-musl-arm.so.1
814        -
815          source: mksh
816          link_name: ${fs_dir}/bin/sh
817        -
818          source: mksh
819          link_name: ${fs_dir}/bin/shell
820      fs_make_cmd:
821        # Create an ext4 image for the rootfs directory using the script.
822        - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4
823    -
824      fs_dir_name: userfs
825      fs_dirs:
826        -
827          source_dir: storage/etc
828          target_dir: etc
829        -
830          source_dir: data
831          target_dir: data
832      fs_make_cmd:
833        - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4
834
835    ```
836
8377.  \(Optional\) Configure patches if the product and modules need to be patched.
838
839    Create the  **patch.yml**  file in the product directory and configure it as required. A typical  **patch.yml**  file is as follows:
840
841    ```
842    # Directory in which the patch is to be installed
843    foundation/communication/dsoftbus:
844      # Directory in which the patch is stored
845      - foundation/communication/dsoftbus/1.patch
846      - foundation/communication/dsoftbus/2.patch
847    third_party/wpa_supplicant:
848      - third_party/wpa_supplicant/1.patch
849      - third_party/wpa_supplicant/2.patch
850      - third_party/wpa_supplicant/3.patch
851    ...
852    ```
853
854    If you add  **--patch**  when running the  **hb build**  command, the patch file can be added to the specified directory before the build.
855
856    ```
857    hb build -f --patch
858    ```
859
8608.  Build the script.
861
862    Create the  **BUILD.gn**  file in the product directory and write the script. The following  **BUILD.gn**  file uses the Wi-Fi IoT module in  [1](#li1970321162111)  as an example:
863
864    ```
865    group("wifiiot") { # The target name must be the same as the product name.
866      deps = []
867      # Copy the init configuration.
868      deps += [ "init_configs" ]
869      # Build the hals directory.
870      deps += [ "hals" ]
871      # Others
872      ......
873    }
874    ```
875
8769.  Build the product.
877
878    Run the  **hb set**  command in the code root directory, select the new product as prompted, and run the  **hb build**  command.
879
880
881## Troubleshooting<a name="section19909721104319"></a>
882
883### Invalid -- w Option<a name="section138233464318"></a>
884
885-   **Symptom**
886
887    The build fails, and "usr/sbin/ninja: invalid option -- w" is displayed.
888
889-   **Cause**
890
891    The Ninja version in the build environment is outdated and does not support the  **--w**  option.
892
893-   **Solution**
894
895    Uninstall Ninja and GN and follow the instructions provided in  [IDE](../get-code/gettools-ide.md)  to install Ninja and GN of the required version.
896
897
898### Library ncurses Not Found<a name="section151033911442"></a>
899
900-   **Symptom**
901
902    The build fails, and "/usr/bin/ld: cannot find -lncurses" is displayed.
903
904-   **Cause**
905
906    The ncurses library is not installed.
907
908-   **Solution**
909
910    ```
911    sudo apt-get install lib32ncurses5-dev
912    ```
913
914
915### mcopy not Found<a name="section19811838104418"></a>
916
917-   **Symptom**
918
919    The build fails, and "line 77: mcopy: command not found" is displayed.
920
921-   **Cause**
922
923    mcopy is not installed.
924
925-   **Solution**
926
927    ```
928    ​sudo apt-get install dosfstools mtools
929    ```
930
931
932### No riscv File or Directory<a name="section03111118451"></a>
933
934-   **Symptom**
935
936    The build fails, and the following information is displayed:
937
938    riscv32-unknown-elf-gcc: error trying to exec 'cc1': execvp: No such file or directory.
939
940-   **Cause**
941
942    Permission is required to access files in the  **riscv**  compiler directory.
943
944-   **Solution**
945
946    Run the following command to query the directory where  **gcc\_riscv32**  is located:
947
948    ```
949    which riscv32-unknown-elf-gcc
950    ```
951
952    Run the  **chmod**  command to change the directory permission to  **755**.
953
954
955### No Crypto<a name="section69981127125013"></a>
956
957-   **Symptom**
958
959    The build fails, and "No module named 'Crypto'" is displayed.
960
961-   **Cause**
962
963    Crypto is not installed in Python 3.
964
965-   **Solution**
966    1.  Run the following command to query the Python version:
967
968        ```
969        python3 --version
970        ```
971
972    2.  Ensure that Python 3.7 or later is installed, and then run the following command to install pycryptodome:
973
974        ```
975        sudo pip3 install pycryptodome
976        ```
977
978
979
980### Unexpected Operator<a name="section967617530505"></a>
981
982-   **Symptom**
983
984    The build fails, and "xx.sh \[: xx unexpected operator" is displayed.
985
986-   **Cause**
987
988    The build environment is shell, not bash.
989
990-   **Solution**
991
992    ```
993    sudo rm -rf /bin/sh
994    sudo ln -s /bin/bash /bin/sh
995    ```
996
997
998