1# Porting a Library Built Using CMake
2
3
4The following shows how to port the double-conversion library.
5
6## Source Code Acquisition
7
8Acquire the source code of double-conversion from [double-conversion](https://github.com/google/double-conversion). The following table lists the directory structure.
9
10**Table 1** Directory structure of the source code
11
12| Directory | Description |
13| -------- | -------- |
14| double-conversion/cmake/ | Template used for building with CMake |
15| double-conversion/double-conversion/ | Directory of source files |
16| double-conversion/msvc/ | - |
17| double-conversion/test/ | Source files of the test cases |
18| double-conversion/.gitignore | - |
19| double-conversion/AUTHORS | - |
20| double-conversion/BUILD | - |
21| double-conversion/CMakeLists.txt | Top-level file used for building with CMake |
22| double-conversion/COPYING | - |
23| double-conversion/Changelog | - |
24| double-conversion/LICENSE | - |
25| double-conversion/Makefile | - |
26| double-conversion/README.md | - |
27| double-conversion/SConstruct | - |
28| double-conversion/WORKSPACE | - |
29
30## Porting Guidelines
31
32Cross-compile the double-conversion library by modifying the toolchain to generate executable files for the OpenHarmony platform and then add these files to the OpenHarmony project by invoking CMake via GN.
33
34## Cross-Compilation
35
36### Compilation Reference
37
38The [README.md](https://github.com/google/double-conversion/blob/master/README.md) file in the code repository details the procedures for compiling the double-conversion library using CMake as well as the testing methods. This document focuses on the building, compilation, and testing of the library. If you have any questions during library porting, refer to the **README.md** file. For porting of other third-party libraries that can be independently built with CMake, you can refer to the compilation guides provided by the libraries.
39
40### Cross-Compilation Settings
41
42The following steps show how to configure and modify the toolchains for cross-compiling the libraries built using CMake to compile executable files for the OpenHarmony platform.
43
441.  Configure the toolchains.
45
46    Add configuration of the clang toolchains to the top-level file **CMakeLists.txt** listed in Table 1.
47
48    ```
49    set(CMAKE_CROSSCOMPILING TRUE)
50    set(CMAKE_SYSTEM_NAME Generic)
51    set(CMAKE_CXX_COMPILER_ID Clang)
52    set(CMAKE_TOOLCHAIN_PREFIX llvm-)
53    # Specify the C compiler (ensure that the path of the toolchain has been added to the PATH environment variable) and its flags. To perform cross-compilation using clang, the --target flag must be specified.
54    set(CMAKE_C_COMPILER clang)
55    set(CMAKE_C_FLAGS "--target=arm-liteos -D__clang__ -march=armv7-a -w")
56    # Specify the C++ compiler (ensure that the path of the toolchain has been added to the PATH environment variable) and its flags. To perform cross-compilation, the --target flag must be specified.
57    set(CMAKE_CXX_COMPILER clang++)
58    set(CMAKE_CXX_FLAGS "--target=arm-liteos -D__clang__ -march=armv7-a -w")
59    # Specify the linker and its flags. --target and --sysroot must be specified. You can specify OHOS_SYSROOT_PATH via the suffix parameter of the cmake command.
60    set(MY_LINK_FLAGS "--target=arm-liteos --sysroot=${OHOS_SYSROOT_PATH}")
61    set(CMAKE_LINKER clang)
62    set(CMAKE_CXX_LINKER clang++)
63    set(CMAKE_C_LINKER clang)
64    set(CMAKE_C_LINK_EXECUTABLE
65        "${CMAKE_C_LINKER} ${MY_LINK_FLAGS} <FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
66    set(CMAKE_CXX_LINK_EXECUTABLE
67        "${CMAKE_CXX_LINKER} ${MY_LINK_FLAGS} <FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
68    # Specify the path for searching chained libraries.
69    set(CMAKE_SYSROOT ${OHOS_SYSROOT_PATH})
70    ```
71
722.  Perform the compilation.
73
74    Run a Linux command to enter the directory \(listed in Table 1) for storing double-conversion source files and then run the following commands:
75
76   ```
77   mkdir build && cd build
78   cmake .. -DBUILD_TESTING=ON -DOHOS_SYSROOT_PATH="..."
79   make -j
80   ```
81
82   **OHOS\_SYSROOT\_PATH** specifies the absolute path where **sysroot** is located. For OpenHarmony, set **OHOS\_SYSROOT\_PATH** to the absolute path of the **out/hispark\__xxx_/ipcamera\_hispark\__xxx_/sysroot** directory. This directory is generated after full compilation is complete. Therefore, complete full compilation before porting.
83
843.  View the result.
85
86    After step 2 is complete, a static library file and test cases are generated in the **build** directory.
87
88    **Table 2** Directory structure of compiled files
89
90    | Directory                                      | Description                       |
91    | -------- | -------- |
92    | double-conversion/build/libdouble-conversion.a | Static library file |
93    | double-conversion/build/test/ | Test cases and CMake cache files |
94    | double-conversion/build/CMakeCache.txt | Cache files during CMake building |
95    | double-conversion/build/CMakeFiles/ | - |
96    | double-conversion/build/cmake_install.cmake | - |
97    | double-conversion/build/CTestTestfile.cmake | - |
98    | double-conversion/build/DartConfiguration.tcl | - |
99    | double-conversion/build/generated/ | - |
100    | double-conversion/build/Makefile | - |
101    | double-conversion/build/Testing/ | - |
102
103
104
105## Library Test
106
1071. Set up the OpenHarmony environment.
108
109   Using Hi3516D V300 as an example, compile the OpenHarmony image and burn it to the development board. For details, see the content related to the small system in [Quick Start Overview](../quick-start/quickstart-overview.md).
110
111   The following screen is displayed after a successful login to the OS.
112
113   **Figure 1** Successful startup of OpenHarmony
114
115   ![](figures/successful-startup-of-openharmony.png "successful-startup-of-openharmony")
116
1172. Mount the **nfs** directory and put the executable file **cctest** into the **test** directory \(listed in Table 2) to the **nfs** directory.
118
1193.  Perform the test cases.
120
121    If the double-conversion library is not cross-compiled, you can execute the test cases by running the **make test** command and obtain the result via CMake. However, this command is not applicable to the library after cross-compilation. This way, you can perform the test cases by executing the generated test case files.
122
123    - After the **nfs** directory is successfully mounted, run the following command to list all items in the test cases:
124
125       ```
126       cd nfs
127       ./cctest --list
128       ```
129
130       Some items are as follows:
131
132
133        ```
134        test-bignum/Assign<
135        test-bignum/ShiftLeft<
136        test-bignum/AddUInt64<
137        test-bignum/AddBignum<
138        test-bignum/SubtractBignum<
139        test-bignum/MultiplyUInt32<
140        test-bignum/MultiplyUInt64<
141        test-bignum/MultiplyPowerOfTen<
142        test-bignum/DivideModuloIntBignum<
143        test-bignum/Compare<
144        test-bignum/PlusCompare<
145        test-bignum/Square<
146        test-bignum/AssignPowerUInt16<
147        test-bignum-dtoa/BignumDtoaVariousDoubles<
148        test-bignum-dtoa/BignumDtoaShortestVariousFloats<
149        test-bignum-dtoa/BignumDtoaGayShortest<
150        test-bignum-dtoa/BignumDtoaGayShortestSingle<
151        test-bignum-dtoa/BignumDtoaGayFixed<
152        test-bignum-dtoa/BignumDtoaGayPrecision<
153        test-conversions/DoubleToShortest<
154        test-conversions/DoubleToShortestSingle<
155        ...
156        ```
157
158    - Run the following command to test **test-bignum**:
159
160
161          ```
162          ./cctest test-bignum
163          ```
164
165       The test is passed if the following information is displayed:
166
167
168          ```
169          Ran 13 tests.
170          ```
171
172
173## Adding the Compiled double-conversion Library to the OpenHarmony Project
174
1751.  Copy the double-conversion library to the OpenHarmony project.
176
177    Copy this library that can be cross-compiled to the **third\_party** directory of OpenHarmony. To avoid modifying the **BUILD.gn** file in the directory of the third-party library to be ported, add a directory to store adaptation files, including **BUILD.gn**, **build\_thirdparty.py**, and **config.gni**, for converting GN to CMake building.
178
179    **Table 3** Directory structure of the ported library
180
181   | Directory                                                    | Description                                                  |
182   | -------- | -------- |
183   | OpenHarmony/third_party/double-conversion/BUILD.gn | GN file for adding the third-party library to the OpenHarmony project |
184   | OpenHarmony/third_party/double-conversion/build_thirdparty.py | Script file for GN to call the **shell** command to convert compilation from GN to CMake |
185   | OpenHarmony/third_party/double-conversion/config.gni | Third-party library compilation configuration file, which can be modified to determine whether the test cases will be used during the building |
186   | OpenHarmony/third_party/double-conversion/double-conversion/ | Directory of the third-party library to be ported |
187
1882. Add the GN file to the CMake adaptation file.
189
190   - The following shows the implementation for building using the newly added **BUILD.gn** file. For other third-party libraries that can be independently compiled using CMake, you only need to change the target paths when porting them to OpenHarmony.
191
192     ```
193     import("config.gni")
194     group("double-conversion") {
195         if (ohos_build_thirdparty_migrated_from_fuchisa == true) {
196             deps = [":make"]
197         }
198     }
199     if (ohos_build_thirdparty_migrated_from_fuchisa == true) {
200         action("make") {
201             script = "//third_party/double-  conversion/build_thirdparty.py"
202             outputs = ["$root_out_dir/log_dc.txt"]
203             exec_path = rebase_path(rebase_path("./build",   ohos_third_party_dir))
204             command = "rm * .* -rf && $CMAKE_TOOLS_PATH/cmake ..   $CMAKE_FLAG $CMAKE_TOOLCHAIN_FLAG && make -j"
205             args = [
206                 "--path=$exec_path",
207                 "--command=${command}"
208             ]
209         }
210     }
211     ```
212
213   -   The newly added **config.gni** file is used to configure the library in the following example implementation. For other third-party libraries that can be independently compiled using CMake, you only need to change the configuration of **CMAKE\_FLAG** when porting them to OpenHarmony.
214
215     ```
216     #CMAKE_FLAG: config compile feature
217     CMAKE_FLAG = "-DBUILD_TESTING=ON -DCMAKE_CXX_STANDARD=11"
218
219     #toolchain: follow up-layer,depend on $ohos_build_compiler
220     if (ohos_build_compiler == "clang") {
221         CMAKE_TOOLCHAIN_FLAG = "-DOHOS_SYSROOT_PATH=${root_out_dir}sysroot"
222     } else {
223         CMAKE_TOOLCHAIN_FLAG = ""
224     }
225
226     #CMake tools path,no need setting if this path already joined to $PATH.
227     CMAKE_TOOLS_PATH = "setting CMake tools path..."
228     ```
229
230   - The following shows the implementation of the newly added **build\_thirdparty.py** file. For other third-party libraries that can be independently compiled using CMake, you can port them to OpenHarmony without modifications.
231
232
233     ```
234     import os
235     import sys
236     from subprocess import Popen
237     import argparse
238     import shlex
239
240     def cmd_exec(command):
241         cmd = shlex.split(command)
242         proc = Popen(cmd)
243         proc.wait()
244         ret_code = proc.returncode
245         if ret_code != 0:
246             raise Exception("{} failed, return code is {}".format(cmd, ret_code))
247
248     def main():
249         parser = argparse.ArgumentParser()
250         parser.add_argument('--path', help='Build path.')
251         parser.add_argument('--command', help='Build command.')
252         parser.add_argument('--enable', help='enable python.', nargs='*')
253         args = parser.parse_args()
254
255         if args.enable:
256             if args.enable[0] == 'false':
257               return
258
259         if args.path:
260             curr_dir = os.getcwd()
261             os.chdir(args.path)
262             if args.command:
263                 if '&&' in args.command:
264                     command = args.command.split('&&')
265                     for data in command:
266                       cmd_exec(data)
267               else:
268                   cmd_exec(args.command)
269           os.chdir(curr_dir)
270
271      if __name__ == '__main__':
272         sys.exit(main())
273     ```
274
275   - Add a configuration item in the configuration file to control compiling of the library. By default, library compilation is disabled.
276
277     For example, add the following configuration to the **//build/lite/ohos\_var.gni** file:
278
279     ```
280     declare_args() {
281         ohos_build_thirdparty_migrated_from_fuchisa = true
282      }
283     ```
284
2853. Build the library.
286
287   Execute the following command:
288
289   ```
290   hb build -T //third_party/double-conversion:double-conversion
291   ```
292
293   If the compilation is successful, a static library file and test cases will be generated in the **build** directory.
294
295 <!--no_check-->
296