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 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> **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 > **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> **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> **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 > **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