1e41f4b71Sopenharmony_ci# OpenHarmony Build Specifications
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Overview
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciThis topic aims to guide OpenHarmony developers to enhance the build reproducibility, maintainability, and quality. The build standards team has analyzed a variety of typical build issues and summarized the build guidelines and recommendations in this topic.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci## General Build Principles
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci**P01 Automate the entire build process.**
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ciManual operations are error-prone and time-consuming. Automate all the build operations to make the build process more efficient and reliable.
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci**P02 Make build projects and build environments code-based.**
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ciUse a high-level build framework such as CMake, Maven, and Gradle to describe build projects, and use Ansible or Dockerfile to describe build environments.
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ciThis principle helps hide the complexity of the build system from developers.
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci**P03 Make the build process reproducible and traceable.**
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ciManage build dependencies and always explicitly specify fixed dependency versions to ensure version consistency. Incorporate build environments and build projects into the configuration file as configuration options to ensure that the build projects are traceable.
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci**P04 Ensure that the build scripts are simple, clear, and easy to maintain.**
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ciBuild scripts are also code and should be easy to read.
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ci**P05 Standardize the build process.**
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ciThe build directory structure, dependencies, initialization, entry, and naming must be standardized to ensure consistency among all OpenHarmony products, platforms, and components for easier management and maintenance.
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ci## Build Projects
32e41f4b71Sopenharmony_ci
33e41f4b71Sopenharmony_ci### General Guidelines
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ci#### One-Click Build
36e41f4b71Sopenharmony_ci
37e41f4b71Sopenharmony_ci##### G.COM.01 Use build scripts to implement one-click, automated build by delivery unit.
38e41f4b71Sopenharmony_ci
39e41f4b71Sopenharmony_ciOne-click, automated build means that no manual interventions are allowed throughout the entire build process (until the final delivery package is generated) in a build environment.
40e41f4b71Sopenharmony_ci
41e41f4b71Sopenharmony_ciManual interventions include but are not limited to: manual parameter setting on the IDE; file directory creation or deletion; file creation, copying, moving, deletion, or renaming; manual setting of file attributes; file compression/decompression. 
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ciDelivery unit refers to a product, platform, or component that can be independently compiled, loaded, deployed, and run.
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ci[Type] Requirement
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ci[Description] One-click build improves operation efficiency while greatly reducing the possibility of operation errors.
48e41f4b71Sopenharmony_ci
49e41f4b71Sopenharmony_ci[Negative Example] The one-click build of a component can be triggered only by the CI system but cannot be triggered locally.
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci[Negative Example] Manually set the memory mapping address on the Xplorer IDE UI for a component, and then perform manual build.
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ci[Negative Example] Manually create the **r6c03_view\r6c03_client_view** directory for a component.
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_ci[Positive Example] Use the python script to automatically create a directory.
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ci```python
58e41f4b71Sopenharmony_cidir_src = os.getcwd()
59e41f4b71Sopenharmony_cidir_client_view = r"r6c03_client_view"
60e41f4b71Sopenharmony_ci# os.path is used to shield system differences.
61e41f4b71Sopenharmony_cidir_mk = os.path.join(dir_src, dir_client_view)
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_cicmd = "{0} {1}".format("mkdir", dir_mk)
64e41f4b71Sopenharmony_cicmd_re = subprocess.run(cmd)
65e41f4b71Sopenharmony_ci```
66e41f4b71Sopenharmony_ci
67e41f4b71Sopenharmony_ci#### Build Directory
68e41f4b71Sopenharmony_ci
69e41f4b71Sopenharmony_ci##### G.COM.02 DO NOT delete or modify source code files and their directory structures during build.
70e41f4b71Sopenharmony_ci
71e41f4b71Sopenharmony_ci[Type] Forbidden
72e41f4b71Sopenharmony_ci
73e41f4b71Sopenharmony_ci[Description]
74e41f4b71Sopenharmony_ci
75e41f4b71Sopenharmony_ci- If the source code directory structure is deleted or modified during the build, the build process will be non-reproducible.
76e41f4b71Sopenharmony_ci
77e41f4b71Sopenharmony_ci- During the build, the build output (including the target files, temporary files, and build logs) should not pollute the source code directory. 
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ci- During the build, do not modify source files, including but not limited to copying, moving, and running **dos2unix** to convert the source code format. Any modification to the source files must be completed in the code preparation phase before the build. 
80e41f4b71Sopenharmony_ci
81e41f4b71Sopenharmony_ci- The tool-triggered, automatic generation of source code must also be completed in the preparation phase before the build. If tools are used to automatically generate source code during the build, the source code generated (low-value and reproducible) must be isolated from the existing source code directory for better distinguishing, so as to reduce the complexity of the build system.
82e41f4b71Sopenharmony_ci
83e41f4b71Sopenharmony_ci[Exception] Some source code may be added or adjusted during patch build.
84e41f4b71Sopenharmony_ci
85e41f4b71Sopenharmony_ci##### G.COM.12 Provide appropriate permissions for files and directories created during the build.
86e41f4b71Sopenharmony_ci
87e41f4b71Sopenharmony_ci[Type] Requirement
88e41f4b71Sopenharmony_ci
89e41f4b71Sopenharmony_ci[Description] Directories or files of the target system that are created during the build must comply with the design of least privilege. For example, do not create directories or files with the **777** permission in the Linux system during the build.
90e41f4b71Sopenharmony_ci
91e41f4b71Sopenharmony_ciFor details about common directory files and permissions in the Linux system, see the *Linux Security Configuration Standard*.
92e41f4b71Sopenharmony_ci
93e41f4b71Sopenharmony_ci#### Build Initialization
94e41f4b71Sopenharmony_ci
95e41f4b71Sopenharmony_ci##### G.COM.03 Provide the clean command for each component.
96e41f4b71Sopenharmony_ci
97e41f4b71Sopenharmony_ci- If the **clean** command is executed with no arguments specified, all target files, temporary files, and build logs in the build project of the current level will be cleared, and the **clean** commands of the lower-level build project are recursively called to restore the build projects to the initial state.
98e41f4b71Sopenharmony_ci- If the **clean** command is executed with certain arguments specified, only the corresponding target files, temporary files, and build logs generated in the specified build will be cleared.
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ci[Type] Requirement
101e41f4b71Sopenharmony_ci
102e41f4b71Sopenharmony_ci[Description] The **clean** command prevents a build from being affected by historical build files and build logs, ensuring build reproducibility. The **clean** command without any arguments must be supported. The **clean** command with arguments applies only to internal delivery and local build.
103e41f4b71Sopenharmony_ci
104e41f4b71Sopenharmony_ci[Positive Example]
105e41f4b71Sopenharmony_ci
106e41f4b71Sopenharmony_ci```
107e41f4b71Sopenharmony_cibase_dir
108e41f4b71Sopenharmony_ci |---build.suffix
109e41f4b71Sopenharmony_ci |---logs
110e41f4b71Sopenharmony_ci |---component_depository_1
111e41f4b71Sopenharmony_ci    |---build.suffix
112e41f4b71Sopenharmony_ci    |---logs
113e41f4b71Sopenharmony_ci |---component_depository_2
114e41f4b71Sopenharmony_ci    |---build.suffix
115e41f4b71Sopenharmony_ci    |---logs
116e41f4b71Sopenharmony_ci
117e41f4b71Sopenharmony_ci# No arguments
118e41f4b71Sopenharmony_cibase_dir/build.suffix clean
119e41f4b71Sopenharmony_ci#....Call clean of component_depository_1 and component_depository_2.
120e41f4b71Sopenharmony_ci
121e41f4b71Sopenharmony_ci# With arguments: component name
122e41f4b71Sopenharmony_cibase_dir/build.suffix clean component_depository_1
123e41f4b71Sopenharmony_ci#....Call clean of component_depository_1 only.
124e41f4b71Sopenharmony_ci
125e41f4b71Sopenharmony_ci# With arguments
126e41f4b71Sopenharmony_cicomponent_depository_1/build.suffix clean makebin hert umpt
127e41f4b71Sopenharmony_ci#....Call clean of the umpt board of component_depository_1.
128e41f4b71Sopenharmony_ci```
129e41f4b71Sopenharmony_ci
130e41f4b71Sopenharmony_ci##### G.COM.04 Clear legacy build files in the build environment before the build of a component.
131e41f4b71Sopenharmony_ci
132e41f4b71Sopenharmony_ci[Type] Requirement
133e41f4b71Sopenharmony_ci
134e41f4b71Sopenharmony_ci[Description] If code is downloaded for the first time and the build environment has been initialized, the build environment does not have legacy build files. In this case, you do not need to run the **clean** command. If build has been performed, run the **clean** command to clear legacy build files.
135e41f4b71Sopenharmony_ci
136e41f4b71Sopenharmony_ci#### Full Build
137e41f4b71Sopenharmony_ci
138e41f4b71Sopenharmony_ci##### G.COM.05 For a version release build, recompile all the archived deliverables (including all dependent platforms and components). DO NOT use incremental build. DO NOT change the installation disk by manually replacing files.
139e41f4b71Sopenharmony_ci
140e41f4b71Sopenharmony_ciA version release build refers to the build of a formally released product version (including all dependent platforms and components).
141e41f4b71Sopenharmony_ci
142e41f4b71Sopenharmony_ci[Type] Requirement
143e41f4b71Sopenharmony_ci
144e41f4b71Sopenharmony_ci[Description] Conducting incremental build after file modification may cause failures in updating some binary files and integrating new security build options into the version, causing inconsistent build results. Manually replacing files may make the build unreproducible and inconsistent.
145e41f4b71Sopenharmony_ci
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ci#### Build Configurations
148e41f4b71Sopenharmony_ci
149e41f4b71Sopenharmony_ciSeparate the build configuration data from the build script to prevent the build project architecture from decaying. Store configuration data, such as the source code path, build options, and target file path, in a file different from the file that stores the build script to minimize the maintenance cost of build scripts.
150e41f4b71Sopenharmony_ci
151e41f4b71Sopenharmony_ci##### G.COM.06 DO NOT use a file that is strongly bound to the operating system (for example, an Excel file) as a build configuration file. Use a file format recognized by different platforms, such as an XML file, as the build configuration file.
152e41f4b71Sopenharmony_ci
153e41f4b71Sopenharmony_ci[Type] Requirement
154e41f4b71Sopenharmony_ci
155e41f4b71Sopenharmony_ci[Description] Using an Excel configuration file brings the following problems:
156e41f4b71Sopenharmony_ci
157e41f4b71Sopenharmony_ci- The file calls Microsoft Office APIs during the build. Each time the Excel file is accessed, the Excel program is started in the background, causing slow responding.
158e41f4b71Sopenharmony_ci
159e41f4b71Sopenharmony_ci- A large number of Excel configurations require manual operations on the GUI, resulting in poor manageability.
160e41f4b71Sopenharmony_ci
161e41f4b71Sopenharmony_ci#### Build Logs
162e41f4b71Sopenharmony_ci
163e41f4b71Sopenharmony_ci##### G.COM.07 Generate simple and clear build logs, and use the format "timestamp + [module name](optional) + log level + log content" for each log record.
164e41f4b71Sopenharmony_ci[Type] Requirement
165e41f4b71Sopenharmony_ci
166e41f4b71Sopenharmony_ciYou are advised to set the timestamp in the format of date and time, for example, *MM/dd/yyyy HH:mm:ss*.
167e41f4b71Sopenharmony_ci
168e41f4b71Sopenharmony_ciLog levels are classified into error, warning (warn), and information (info), either in lowercase or uppercase.
169e41f4b71Sopenharmony_ci
170e41f4b71Sopenharmony_ciYou are advised to use square brackets ([]) to enclose each part of a log record.
171e41f4b71Sopenharmony_ci
172e41f4b71Sopenharmony_ci[Positive Example]
173e41f4b71Sopenharmony_ci
174e41f4b71Sopenharmony_ci[05/21/2020 00:12:40] [ERROR] mkdir: cannot create directory Permission denied.
175e41f4b71Sopenharmony_ci
176e41f4b71Sopenharmony_ci[Exception] If the entire log is automatically generated by a tool, you can skip the log file in the following way: Output "This project is built using + *tool name*" at the beginning of the log, for example, "This project is built using CMake."
177e41f4b71Sopenharmony_ci
178e41f4b71Sopenharmony_ci##### G.COM.08 Stop the build if error is displayed in the log.
179e41f4b71Sopenharmony_ci
180e41f4b71Sopenharmony_ci[Type] Requirement
181e41f4b71Sopenharmony_ci
182e41f4b71Sopenharmony_ci[Description] An error log indicates a build error that requires manual intervention, for example, an incorrect environment variable, tool version error, operating system error, or incorrect software source code. For a version release build, all errors generated during the build must be eliminated. DO NOT shield build errors.
183e41f4b71Sopenharmony_ci
184e41f4b71Sopenharmony_ci[Negative Example] A component is successfully built, but the build log contains a large amount of exception information, such as "fail", "critical", "cannot", "not found", "missing" and "no input files".
185e41f4b71Sopenharmony_ci
186e41f4b71Sopenharmony_ci##### G.COM.09 Retain only the logs of the current build in the build log file.
187e41f4b71Sopenharmony_ci
188e41f4b71Sopenharmony_ci[Type] Requirement
189e41f4b71Sopenharmony_ci
190e41f4b71Sopenharmony_ci[Description] Retaining historical build logs in the build log file may cause confusing. For example, when a new build fails, users may confuse the logs of historical successful builds with those of the new build and mistakenly consider the new build successful.
191e41f4b71Sopenharmony_ci
192e41f4b71Sopenharmony_ci##### G.COM.10 Add the corresponding module name to each log for quick fault locating.
193e41f4b71Sopenharmony_ci
194e41f4b71Sopenharmony_ci[Type] Recommendation
195e41f4b71Sopenharmony_ci
196e41f4b71Sopenharmony_ci[Description] If there are a large number of logs, it is difficult to quickly locate the module involved in a specific fault. Adding the corresponding module name facilitates quick fault locating.
197e41f4b71Sopenharmony_ci
198e41f4b71Sopenharmony_ci[Exception] The native logs of tools such as CMake contain the module paths, which can be used to locate the modules. For such logs, you do not need to add the module name information.
199e41f4b71Sopenharmony_ci
200e41f4b71Sopenharmony_ci#### Build Users
201e41f4b71Sopenharmony_ci
202e41f4b71Sopenharmony_ci##### G.COM.11 DO NOT use the super administrator **root** or system user for build. Instead, use a common user account.
203e41f4b71Sopenharmony_ci
204e41f4b71Sopenharmony_ci[Type] Requirement
205e41f4b71Sopenharmony_ci
206e41f4b71Sopenharmony_ci[Description] The super administrator **root** and system user have high system permissions. Using such an account for the build may cause the build environment to be tampered with.
207e41f4b71Sopenharmony_ci
208e41f4b71Sopenharmony_ciIn the installation state, the **root** user account can be used. In the running state, use a common user account. If you need to run the **sudo** command for privilege escalation, comply with *IAM Security Design Specifications*.
209e41f4b71Sopenharmony_ci
210e41f4b71Sopenharmony_ci#### Build Output Files
211e41f4b71Sopenharmony_ci
212e41f4b71Sopenharmony_ci##### G.COM.12 Follow the industry conventions for build output file name extensions.
213e41f4b71Sopenharmony_ci
214e41f4b71Sopenharmony_ci[Type] Requirement
215e41f4b71Sopenharmony_ci
216e41f4b71Sopenharmony_ci[Description] An incorrect file name extension is misleading.
217e41f4b71Sopenharmony_ci
218e41f4b71Sopenharmony_ciThe file name extensions of the output files, such as .lib and .obj files, must comply with the default naming rules of the build tools.
219e41f4b71Sopenharmony_ci
220e41f4b71Sopenharmony_ci[Negative Example] A text file is named ***Example*.lib**.
221e41f4b71Sopenharmony_ci
222e41f4b71Sopenharmony_ci[Negative Example] An object file is named ***Example*.a**.
223e41f4b71Sopenharmony_ci
224e41f4b71Sopenharmony_ci[Negative Example] A static library is named **lib*Example***, without a file name extension.
225e41f4b71Sopenharmony_ci
226e41f4b71Sopenharmony_ci[Positive Example] Query the common file name extension conventions at http://www.fileextension.org/, https://fileinfo.com/, https://www.file-extensions.org/, and http://file-extension.net/.
227e41f4b71Sopenharmony_ci
228e41f4b71Sopenharmony_ciConventions about common file name extensions are as follows:
229e41f4b71Sopenharmony_ci
230e41f4b71Sopenharmony_ci| File Name Extension| Type Convention            | File Name Extension| Type Convention       |
231e41f4b71Sopenharmony_ci| ---------- | -------------------- | ---------- | --------------- |
232e41f4b71Sopenharmony_ci| .a         | Static library              | .so        | Dynamic library         |
233e41f4b71Sopenharmony_ci| .o         | Object file          | .7z        | 7-zip compressed file   |
234e41f4b71Sopenharmony_ci| .tar       | TAR archive file         | .gz/.gzip  | GNU zip archive file|
235e41f4b71Sopenharmony_ci| .pack      | Java pack200 compressed file| .rar/.rar5 | RAR compressed file      |
236e41f4b71Sopenharmony_ci
237e41f4b71Sopenharmony_ci### C/C++ Build Projects
238e41f4b71Sopenharmony_ci
239e41f4b71Sopenharmony_ci#### Build Directory
240e41f4b71Sopenharmony_ci
241e41f4b71Sopenharmony_ci##### G.C&C++.01 Standardize the build directory structure.
242e41f4b71Sopenharmony_ci
243e41f4b71Sopenharmony_ciBuild directories are classified into Source Tree, Build Tree, and Install Tree by functionality.
244e41f4b71Sopenharmony_ci
245e41f4b71Sopenharmony_ci- Source Tree is the directory for storing source code and build scripts.
246e41f4b71Sopenharmony_ci- Build Tree is the directory for storing build middleware. Generally, the directory name is **build**.
247e41f4b71Sopenharmony_ci- Install Tree is the directory for storing build deliverables. The directory name is fixed at **output**.
248e41f4b71Sopenharmony_ci
249e41f4b71Sopenharmony_ciThe Source Tree, Build Tree, and Install Tree directories should be isolated from each other and should not overlap. One directory cannot be used for two or more purposes. For example, it is prohibited that a directory is used as both Source Tree to store source code and Build Tree to store build middleware.
250e41f4b71Sopenharmony_ci
251e41f4b71Sopenharmony_ciSource Tree contains the following files and directories:
252e41f4b71Sopenharmony_ci
253e41f4b71Sopenharmony_ci- Build tool entry file, such as **CMakeLists.txt**. After the **add_subdirectory()** command is executed in the upper-level **CMakeLists.txt** file, the CMake automatically invokes the **CMakeLists.txt** files in the subdirectory and lower-level subdirectories.
254e41f4b71Sopenharmony_ci- **build.*suffix*** script file, which is the one-click build entry. You only need to invoke this script to complete the build. In the build entry file name, *.suffix* (such as .bat, .sh, or .py) indicates the programming language used by the build script.
255e41f4b71Sopenharmony_ci- **config.*suffix*** configuration file, which is used to store build options and is the unique entry for configuration.
256e41f4b71Sopenharmony_ci- Build script directory, which is optional. For example, the **cmake** directory is used to store CMake scripts. CMake script files include macros, functions, and the toolchain. The **CMakeLists.txt** script contains CMake script files by executing the **include()** command, and invokes the macros and functions in the script files.
257e41f4b71Sopenharmony_ci- Component code directory, which is used to store source code and build scripts of each component.
258e41f4b71Sopenharmony_ci
259e41f4b71Sopenharmony_ciAmong the preceding files and directories, only the **CMakeLists.txt**, **build.*suffix***, and **config.*suffix*** files are mandatory. Other files and directories are optional and provided as examples for your better understanding.
260e41f4b71Sopenharmony_ci
261e41f4b71Sopenharmony_ciBuild Tree contains the following directories:
262e41f4b71Sopenharmony_ci
263e41f4b71Sopenharmony_ci- **build** directory, which is used to store the build middleware. This directory may be created during the build process and may not exist in the Git repository. If the **build** directory is used to store build scripts, you can create another directory as Build Tree.
264e41f4b71Sopenharmony_ci
265e41f4b71Sopenharmony_ciInstall Tree contains the following directories:
266e41f4b71Sopenharmony_ci
267e41f4b71Sopenharmony_ci- **output** directory, which is used to store deliverables. This directory may be created during the build process and may not exist in the Git repository.
268e41f4b71Sopenharmony_ci
269e41f4b71Sopenharmony_ci[Type] Requirement
270e41f4b71Sopenharmony_ci
271e41f4b71Sopenharmony_ci[Description]
272e41f4b71Sopenharmony_ci
273e41f4b71Sopenharmony_ciA typical directory structure is as follows:
274e41f4b71Sopenharmony_ci
275e41f4b71Sopenharmony_ci```
276e41f4b71Sopenharmony_cibase_dir
277e41f4b71Sopenharmony_ci |---CMakeLists.txt      ---|
278e41f4b71Sopenharmony_ci |---build.suffix           |
279e41f4b71Sopenharmony_ci |---config.suffix          |
280e41f4b71Sopenharmony_ci |---cmake                  |--> Source Tree
281e41f4b71Sopenharmony_ci |---component_1            |
282e41f4b71Sopenharmony_ci |---component_2            |
283e41f4b71Sopenharmony_ci |---......                 |
284e41f4b71Sopenharmony_ci |---component_n         ---|
285e41f4b71Sopenharmony_ci |---build               ------> Build Tree
286e41f4b71Sopenharmony_ci |---output              ------> Install Tree
287e41f4b71Sopenharmony_ci```
288e41f4b71Sopenharmony_ci
289e41f4b71Sopenharmony_ciThe directory structure of each component is similar to the top directory structure. Example:
290e41f4b71Sopenharmony_ci
291e41f4b71Sopenharmony_ci```
292e41f4b71Sopenharmony_cicomponent_1
293e41f4b71Sopenharmony_ci |---CMakeLists.txt      ---|
294e41f4b71Sopenharmony_ci |---build.suffix           |
295e41f4b71Sopenharmony_ci |---config.suffix          |
296e41f4b71Sopenharmony_ci |---cmake                  |--> Source Tree
297e41f4b71Sopenharmony_ci |---module_1               |
298e41f4b71Sopenharmony_ci |---module_2               |
299e41f4b71Sopenharmony_ci |---......                 |
300e41f4b71Sopenharmony_ci |---module_n            ---|
301e41f4b71Sopenharmony_ci |---build               ------> Build Tree
302e41f4b71Sopenharmony_ci |---output              ------> Install Tree
303e41f4b71Sopenharmony_ci```
304e41f4b71Sopenharmony_ci
305e41f4b71Sopenharmony_ci##### G.C&C++.02 DO NOT modify Source Tree in any form during the build process.
306e41f4b71Sopenharmony_ci
307e41f4b71Sopenharmony_ci[Type] Recommendation
308e41f4b71Sopenharmony_ci
309e41f4b71Sopenharmony_ci[Description] If Source Tree is modified during the build, the build process will be non-reproducible.
310e41f4b71Sopenharmony_ci
311e41f4b71Sopenharmony_ciThe common operations for modifying Source Tree are as follows:
312e41f4b71Sopenharmony_ci
313e41f4b71Sopenharmony_ci- Patch installation
314e41f4b71Sopenharmony_ci- Dotting
315e41f4b71Sopenharmony_ci- Tailoring
316e41f4b71Sopenharmony_ci- Automatic source code generation
317e41f4b71Sopenharmony_ci- Modifying source code and then restoring it
318e41f4b71Sopenharmony_ci- Adding, modifying, or deleting temporary files or directories
319e41f4b71Sopenharmony_ci- Modifying the attribute or format of a file or directory (For example, modify the execute permission of a file or **dos2unix**.)
320e41f4b71Sopenharmony_ci
321e41f4b71Sopenharmony_ciRecommended operations are as follows:
322e41f4b71Sopenharmony_ci
323e41f4b71Sopenharmony_ci(1) Copy code to Build Tree, install a patch, and build the code.
324e41f4b71Sopenharmony_ci
325e41f4b71Sopenharmony_ci(2) As the dotting tool modifies source code and makes the build process untrustworthy, do not use the dotting tool during the build. Instead, upload the dotted code to the code repository and use the dotted code for the build.
326e41f4b71Sopenharmony_ci
327e41f4b71Sopenharmony_ci(3) Tailoring is an independent source code delivery requirement and can be considered as the code preparation phase. Source Tree in the versions before and after tailoring must not be modified during the build.
328e41f4b71Sopenharmony_ci
329e41f4b71Sopenharmony_ci(4) The automatically generated source code must be stored in Build Tree.
330e41f4b71Sopenharmony_ci
331e41f4b71Sopenharmony_ci(5) Modifying and then restoring source code is prohibited because the source code has changed during the build.
332e41f4b71Sopenharmony_ci
333e41f4b71Sopenharmony_ci(6) Temporary files or directories must be stored in Build Tree.
334e41f4b71Sopenharmony_ci
335e41f4b71Sopenharmony_ci(7) Ensure that the attributes and formats of files in the code repository are correct to prevent modifying them during the build.
336e41f4b71Sopenharmony_ci
337e41f4b71Sopenharmony_ciTo check for Source Tree changes, run the **git status** command in the source code directory after the build. Source Tree should not have any change. The **git status** command may fail to detect changes to Source Tree where source code is modified and then restored.
338e41f4b71Sopenharmony_ci
339e41f4b71Sopenharmony_ci[Exception]
340e41f4b71Sopenharmony_ci
341e41f4b71Sopenharmony_ci(1) Changes in the Build Tree and Install Tree directories detected by the **git status** command are allowed.
342e41f4b71Sopenharmony_ci
343e41f4b71Sopenharmony_ci(2) Tailoring-caused changes detected by the **git status** command are allowed.
344e41f4b71Sopenharmony_ci
345e41f4b71Sopenharmony_ci##### G.C&C++.03 Use D:\*deliveryUnitName + versionNumber (optional)* and /usr1/*deliveryUnitName + versionNumber (optional)* as the build root directory in Windows and Linux, respectively.
346e41f4b71Sopenharmony_ci
347e41f4b71Sopenharmony_ci[Type] Recommendation
348e41f4b71Sopenharmony_ci
349e41f4b71Sopenharmony_ci[Description] Name the build root directory in the format of *deliveryUnitName + versionNumber*, where *versionNumber* is optional. DO NOT use the directory name that cannot identify a specific delivery unit, such as **build** or **code**.
350e41f4b71Sopenharmony_ci
351e41f4b71Sopenharmony_ciA clear build directory structure helps test personnel set build parameters, execute one-click build entries, and compare build results.
352e41f4b71Sopenharmony_ci
353e41f4b71Sopenharmony_ciThe following are two root directory examples:
354e41f4b71Sopenharmony_ci
355e41f4b71Sopenharmony_ci```
356e41f4b71Sopenharmony_ciD:\Offering [Version (optional)] or /usr1/Offering [Version (optional)]
357e41f4b71Sopenharmony_ci```
358e41f4b71Sopenharmony_ci
359e41f4b71Sopenharmony_ci##### G.C&C++.04 Store all middleware generated during the build in Build Tree.
360e41f4b71Sopenharmony_ci
361e41f4b71Sopenharmony_ci[Type] Requirement
362e41f4b71Sopenharmony_ci
363e41f4b71Sopenharmony_ci[Description] The middleware generated during the build includes the makefile automatically generated by the build tool CMake, the source code automatically generated by the build script, the source code and patches copied by the build script, as well as the object files, repository files, executable programs, and build logs generated during the build. Store the middleware in Build Tree only, to avoid pollution to Source Tree or Install Tree. Do not store anything else in Build Tree.
364e41f4b71Sopenharmony_ciCreate the **logs** subdirectory under Build Tree and name build log files in .log format.
365e41f4b71Sopenharmony_ci
366e41f4b71Sopenharmony_ci##### G.C&C++.05 You can specify any directory except Source Tree and Install Tree as Build Tree.
367e41f4b71Sopenharmony_ci
368e41f4b71Sopenharmony_ci[Type] Requirement
369e41f4b71Sopenharmony_ci
370e41f4b71Sopenharmony_ci[Description] You can specify any directory other than Source Tree and Install Tree as Build Tree. In this way, the build process is irrelevant to the directory. The directory where the build is executed is Build Tree, and the build middleware is stored in this directory. Generally, the Build Tree directory name is **build**. You can also use another name.
371e41f4b71Sopenharmony_ci
372e41f4b71Sopenharmony_ci[Positive Example] Use CMake system variables **CMAKE_BINARY_DIR** and **CMAKE_CURRENT_BINARY_DIR** to access Build Tree to prevent coupling between Build Tree and Source Tree.
373e41f4b71Sopenharmony_ci
374e41f4b71Sopenharmony_ci##### G.C&C++.06 Store all deliverables in Install Tree.
375e41f4b71Sopenharmony_ci
376e41f4b71Sopenharmony_ci[Type] Requirement
377e41f4b71Sopenharmony_ci
378e41f4b71Sopenharmony_ci[Description] In the local build scenario, deliverables are directly installed on the host computer and run. In the cross-build scenario, deliverables run on the target computer.
379e41f4b71Sopenharmony_ci
380e41f4b71Sopenharmony_ciThe deliverables include library files, executable programs, package files, and header files. They are binary interfaces provided by components. All the deliverables must be stored in Install Tree.
381e41f4b71Sopenharmony_ci
382e41f4b71Sopenharmony_ciDo not place any file other than deliverables (such as build middleware) in Install Tree.
383e41f4b71Sopenharmony_ci
384e41f4b71Sopenharmony_ci##### G.C&C++.07 You can specify any directory except Source Tree and Build Tree as Install Tree.
385e41f4b71Sopenharmony_ci
386e41f4b71Sopenharmony_ci[Type] Requirement
387e41f4b71Sopenharmony_ci
388e41f4b71Sopenharmony_ci[Description] You can specify any directory other than Source Tree and Build Tree as Install Tree. In this way, the build process is irrelevant to the directory. The Install Tree directory name is fixed at **output**.
389e41f4b71Sopenharmony_ci
390e41f4b71Sopenharmony_ci[Positive Example] The CMake build project supports the function of specifying the Install Tree directory through the system variable **CMAKE_INSTALL_PREFIX**.
391e41f4b71Sopenharmony_ci
392e41f4b71Sopenharmony_ci#### Build Entry
393e41f4b71Sopenharmony_ci
394e41f4b71Sopenharmony_ci##### G.C&C++.08 Provide a unique build entry for each delivery unit. Name all the build entry scripts in the **build.*suffix*** format, and store them in the build root directory.
395e41f4b71Sopenharmony_ci
396e41f4b71Sopenharmony_ci[Type] Requirement
397e41f4b71Sopenharmony_ci
398e41f4b71Sopenharmony_ci[Description] A unique build entry allows for a more efficient and automated build process. Each delivery unit has a unique build entry, making one-click, automated build possible.
399e41f4b71Sopenharmony_ci
400e41f4b71Sopenharmony_ci[Negative Example] The following build has multiple entry points. If no description document is provided, it is difficult to determine which entry point is correct.
401e41f4b71Sopenharmony_ci
402e41f4b71Sopenharmony_cibuild.bat 
403e41f4b71Sopenharmony_ci
404e41f4b71Sopenharmony_cibuild_all.sh 
405e41f4b71Sopenharmony_ci
406e41f4b71Sopenharmony_cibuild_v6.sh 
407e41f4b71Sopenharmony_ci
408e41f4b71Sopenharmony_ci[Positive Example] A typical one-click build script **build.sh** is as follows:
409e41f4b71Sopenharmony_ci
410e41f4b71Sopenharmony_ci```bash
411e41f4b71Sopenharmony_ci#!/bin/bash
412e41f4b71Sopenharmony_ci
413e41f4b71Sopenharmony_ciif [ -d "build" ]; then
414e41f4b71Sopenharmony_ci    rm -fr build/*
415e41f4b71Sopenharmony_cielse
416e41f4b71Sopenharmony_ci    mkdir build
417e41f4b71Sopenharmony_cifi
418e41f4b71Sopenharmony_ci
419e41f4b71Sopenharmony_ciif [ -d "output" ]; then
420e41f4b71Sopenharmony_ci    rm -fr output/*
421e41f4b71Sopenharmony_cielse
422e41f4b71Sopenharmony_ci    mkdir output
423e41f4b71Sopenharmony_cifi
424e41f4b71Sopenharmony_ci
425e41f4b71Sopenharmony_cicd build
426e41f4b71Sopenharmony_cicmake ..
427e41f4b71Sopenharmony_ci
428e41f4b71Sopenharmony_cicpu_processor_num=$(grep processor /proc/cpuinfo | wc -l)
429e41f4b71Sopenharmony_cijob_num=$(expr "$cpu_processor_num" \* 2)
430e41f4b71Sopenharmony_ciecho Parallel job num is "$job_num"
431e41f4b71Sopenharmony_cimake -j"$job_num"
432e41f4b71Sopenharmony_ci```
433e41f4b71Sopenharmony_ci
434e41f4b71Sopenharmony_ci##### G.C&C++.09 You can specify the build target.
435e41f4b71Sopenharmony_ci
436e41f4b71Sopenharmony_ci[Type] Requirement
437e41f4b71Sopenharmony_ci
438e41f4b71Sopenharmony_ci[Description] In routine development scenarios, you can specify the target to build modified code. A project can be built by specifying the target to meet flexible build and debugging requirements.
439e41f4b71Sopenharmony_ci
440e41f4b71Sopenharmony_ci[Positive Example] A typical command is as follows:
441e41f4b71Sopenharmony_ci
442e41f4b71Sopenharmony_ci```
443e41f4b71Sopenharmony_cibase_dir # cd build
444e41f4b71Sopenharmony_cibase_dir/build # cmake ..
445e41f4b71Sopenharmony_ci# Build all targets.
446e41f4b71Sopenharmony_cibase_dir/build # make
447e41f4b71Sopenharmony_ci# Build a specific target.
448e41f4b71Sopenharmony_cibase_dir/build # make target_name
449e41f4b71Sopenharmony_ci```
450e41f4b71Sopenharmony_ci
451e41f4b71Sopenharmony_ci##### G.C&C++.10 Reproducible build is supported.
452e41f4b71Sopenharmony_ci
453e41f4b71Sopenharmony_ci[Type] Requirement
454e41f4b71Sopenharmony_ci
455e41f4b71Sopenharmony_ci[Description] If you do not modify the source code, clear the middleware and deliverables, or modify the build environment after the last successful build, you can perform a new round of build and obtain the same result.
456e41f4b71Sopenharmony_ci
457e41f4b71Sopenharmony_ci##### G.C&C++.11 Incremental build is supported.
458e41f4b71Sopenharmony_ci
459e41f4b71Sopenharmony_ci[Type] Recommendation
460e41f4b71Sopenharmony_ci
461e41f4b71Sopenharmony_ci[Description] In routine development scenarios, incremental build can improve development efficiency. Therefore, it is advised to support incremental build.
462e41f4b71Sopenharmony_ci
463e41f4b71Sopenharmony_ci##### G.C&C++.12 Parallel build is supported.
464e41f4b71Sopenharmony_ci
465e41f4b71Sopenharmony_ci[Type] Requirement
466e41f4b71Sopenharmony_ci
467e41f4b71Sopenharmony_ci[Description] You can run the **make -jN** command for quicker parallel build. This guideline applies only to projects that use the make tool.
468e41f4b71Sopenharmony_ci
469e41f4b71Sopenharmony_ciSupport unified scheduling in jobserver mode to optimize the project load to the best level. The following alarms are not allowed:
470e41f4b71Sopenharmony_ci
471e41f4b71Sopenharmony_ci```
472e41f4b71Sopenharmony_ciwarning: jobserver unavailable: using -j1.  Add '+' to parent make rule.
473e41f4b71Sopenharmony_ciwarning: -jN forced in submake: disabling jobserver mode.
474e41f4b71Sopenharmony_ci```
475e41f4b71Sopenharmony_ci
476e41f4b71Sopenharmony_ciTo support the jobserver mode, perform any of the following operations:
477e41f4b71Sopenharmony_ci
478e41f4b71Sopenharmony_ci1. Use **$(MAKE)** to directly invoke the **make** command.
479e41f4b71Sopenharmony_ci
480e41f4b71Sopenharmony_ci    ```cmake
481e41f4b71Sopenharmony_ci    ExternalProject_Add(foo
482e41f4b71Sopenharmony_ci        SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/foo
483e41f4b71Sopenharmony_ci        CONFIGURE_COMMAND sh configure_ext.sh
484e41f4b71Sopenharmony_ci        BUILD_COMMAND $(MAKE)
485e41f4b71Sopenharmony_ci    )
486e41f4b71Sopenharmony_ci    ```
487e41f4b71Sopenharmony_ci
488e41f4b71Sopenharmony_ci2. Use the shell script to invoke the **make** command.
489e41f4b71Sopenharmony_ci
490e41f4b71Sopenharmony_ci    ```cmake
491e41f4b71Sopenharmony_ci    ExternalProject_Add(foo
492e41f4b71Sopenharmony_ci        SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/foo
493e41f4b71Sopenharmony_ci        CONFIGURE_COMMAND sh configure_ext.sh
494e41f4b71Sopenharmony_ci        BUILD_COMMAND sh build_ext.sh $(MAKE)
495e41f4b71Sopenharmony_ci    )
496e41f4b71Sopenharmony_ci    ```
497e41f4b71Sopenharmony_ci
498e41f4b71Sopenharmony_ci   The content of **build_ext.sh** is as follows:
499e41f4b71Sopenharmony_ci
500e41f4b71Sopenharmony_ci    ```bash
501e41f4b71Sopenharmony_ci    #!/bin/bash
502e41f4b71Sopenharmony_ci
503e41f4b71Sopenharmony_ci    make
504e41f4b71Sopenharmony_ci    ```
505e41f4b71Sopenharmony_ci
506e41f4b71Sopenharmony_ci   Note: **build_ext.sh** does not need to parse or use the **$(MAKE)** parameter.
507e41f4b71Sopenharmony_ci
508e41f4b71Sopenharmony_ci3. Use the python script to invoke the **make** command.
509e41f4b71Sopenharmony_ci
510e41f4b71Sopenharmony_ci    ```cmake
511e41f4b71Sopenharmony_ci    ExternalProject_Add(foo
512e41f4b71Sopenharmony_ci        SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/foo
513e41f4b71Sopenharmony_ci        CONFIGURE_COMMAND sh configure_ext.sh
514e41f4b71Sopenharmony_ci        BUILD_COMMAND python build_ext.py $(MAKE)
515e41f4b71Sopenharmony_ci    )
516e41f4b71Sopenharmony_ci    ```
517e41f4b71Sopenharmony_ci
518e41f4b71Sopenharmony_ci   The content of **build_ext.py** is as follows:
519e41f4b71Sopenharmony_ci
520e41f4b71Sopenharmony_ci    ```bash
521e41f4b71Sopenharmony_ci    #!/usr/bin/python
522e41f4b71Sopenharmony_ci    # -*- coding: UTF-8 -*-
523e41f4b71Sopenharmony_ci
524e41f4b71Sopenharmony_ci    import subprocess
525e41f4b71Sopenharmony_ci
526e41f4b71Sopenharmony_ci    def main():
527e41f4b71Sopenharmony_ci        child = subprocess.Popen("make", close_fds=False)
528e41f4b71Sopenharmony_ci        ret = child.wait()
529e41f4b71Sopenharmony_ci        return
530e41f4b71Sopenharmony_ci            
531e41f4b71Sopenharmony_ci    if __name__ == '__main__':
532e41f4b71Sopenharmony_ci        main()
533e41f4b71Sopenharmony_ci    ```
534e41f4b71Sopenharmony_ci
535e41f4b71Sopenharmony_ci    Note: **build_ext.py** does not need to parse or use the **$(MAKE)** parameter.
536e41f4b71Sopenharmony_ci
537e41f4b71Sopenharmony_ci
538e41f4b71Sopenharmony_ci#### Build Dependencies
539e41f4b71Sopenharmony_ci
540e41f4b71Sopenharmony_ci##### G.C&C++.13 Define a build dependency file **dependence.xml** to describe all components on which the build depends. The build script automatically reads the dependency file to produce the final software package.
541e41f4b71Sopenharmony_ci
542e41f4b71Sopenharmony_ci[Type] Recommendation
543e41f4b71Sopenharmony_ci
544e41f4b71Sopenharmony_ci[Description] Make software packages based on the dependency file, so that you do not need to define dependency components in the build scripts. This improves the build process maintainability.
545e41f4b71Sopenharmony_ci
546e41f4b71Sopenharmony_ci#### Build Configurations
547e41f4b71Sopenharmony_ci
548e41f4b71Sopenharmony_ci##### G.C&C++.14 Use the configuration file **config.*suffix*** in the build root directory as the unique configuration entry for the entire delivery project.
549e41f4b71Sopenharmony_ci
550e41f4b71Sopenharmony_ci[Type] Requirement
551e41f4b71Sopenharmony_ci
552e41f4b71Sopenharmony_ci[Description] Expose the least configuration options in the top-level **config.*suffix*** file. Configure only the information about the build environment and build tool in this file.
553e41f4b71Sopenharmony_ci
554e41f4b71Sopenharmony_ci[Exception] If there are a small number of build options and key-value pairs are used, the configuration file can be named **config.conf**.
555e41f4b71Sopenharmony_ci
556e41f4b71Sopenharmony_ci### GN Build Specifications
557e41f4b71Sopenharmony_ci
558e41f4b71Sopenharmony_ci#### Build Rules
559e41f4b71Sopenharmony_ci
560e41f4b71Sopenharmony_ci##### Rule 1.1 DO NOT use GN to invoke external build tools to build software modules.
561e41f4b71Sopenharmony_ci
562e41f4b71Sopenharmony_ci[Type] Forbidden
563e41f4b71Sopenharmony_ci
564e41f4b71Sopenharmony_ci[Description] Port external components to the GN build mode to avoid unnecessary dependencies on the environment during the build and obtain common capabilities, such as compiler security options and AddressSanitizer (ASan), provided by the build framework.
565e41f4b71Sopenharmony_ci
566e41f4b71Sopenharmony_ci[Negative Example] In GN, use **action** to invoke **automake** and **Make** to build third-party components.
567e41f4b71Sopenharmony_ci
568e41f4b71Sopenharmony_ci[Exception] The Linux kernel build framework builds user-mode programs. The kernel can be independently built outside the build framework. It is acceptable that some platforms use GN to include the kernel build in the build process to deliver one-click builds.
569e41f4b71Sopenharmony_ci
570e41f4b71Sopenharmony_ci##### Rule 1.2 DO NOT add compiler security options that have been added to the build system to the GN file of the module.
571e41f4b71Sopenharmony_ci
572e41f4b71Sopenharmony_ci[Type] Forbidden
573e41f4b71Sopenharmony_ci
574e41f4b71Sopenharmony_ci[Description] The default options that have been added globally should not be added again to meet internal and external rules.
575e41f4b71Sopenharmony_ci
576e41f4b71Sopenharmony_ci| Option| Parameter   | Default Value    |
577e41f4b71Sopenharmony_ci|---------|------------|------------|
578e41f4b71Sopenharmony_ci| Stack protection  | -fstack-protector-strong| Enabled|
579e41f4b71Sopenharmony_ci| Fortify Source | -D_FORTIFY_SOURCE=2 -O2	| Enabled|
580e41f4b71Sopenharmony_ci
581e41f4b71Sopenharmony_ci[Negative Example] Add **-fstack-protector-strong** to the GN file of the module.
582e41f4b71Sopenharmony_ci
583e41f4b71Sopenharmony_ci##### Rule 1.3 DO NOT add build options that are opposite to the default build options to GN.
584e41f4b71Sopenharmony_ci
585e41f4b71Sopenharmony_ci[Type] Forbidden
586e41f4b71Sopenharmony_ci
587e41f4b71Sopenharmony_ci[Description] The default build options represent the default capabilities of the build system. If your module needs to remove some default build options, there must be sufficient reasons.
588e41f4b71Sopenharmony_ci
589e41f4b71Sopenharmony_ci[Negative Example] Add **-wno-unused** to a module to clear build alarms.
590e41f4b71Sopenharmony_ci
591e41f4b71Sopenharmony_ci[Exception] When porting or using a third-party component, you can overwrite the default build options based on the component requirements.
592e41f4b71Sopenharmony_ci
593e41f4b71Sopenharmony_ci##### Rule 2.1 Use **gn format** to format GN files to meet the format and typesetting requirements.
594e41f4b71Sopenharmony_ci
595e41f4b71Sopenharmony_ci[Type] Requirement
596e41f4b71Sopenharmony_ci
597e41f4b71Sopenharmony_ci##### Rule 2.2 Use Python instead of shell to compile **action**.
598e41f4b71Sopenharmony_ci
599e41f4b71Sopenharmony_ci[Type] Recommendation
600e41f4b71Sopenharmony_ci
601e41f4b71Sopenharmony_ci[Description] The Python environment is easier to keep code unified and can run on multiple operating systems. It also provides better scalability, readability, and testability.
602e41f4b71Sopenharmony_ci
603e41f4b71Sopenharmony_ci##### Rule 2.3 DO NOT modify the content in the source code directory during the execution of GN and Ninja.
604e41f4b71Sopenharmony_ci
605e41f4b71Sopenharmony_ci[Type] Forbidden
606e41f4b71Sopenharmony_ci
607e41f4b71Sopenharmony_ci[Description] The forbidden operations include but are not limited to installing patches for, copying files to, performing build tasks in, and generating intermediate files in the source code directory.
608e41f4b71Sopenharmony_ci
609e41f4b71Sopenharmony_ci##### Rule 2.4 Set the encoding format of the build script to UTF-8 and the newline character to UNIX format.
610e41f4b71Sopenharmony_ci
611e41f4b71Sopenharmony_ci[Type] Requirement
612e41f4b71Sopenharmony_ci
613e41f4b71Sopenharmony_ci[Negative Example] After a script is compiled on Windows, Chinese comments are used and saved as local codes.