gn是什么?
gn
存在的意义是为了生成 ninja
,如果熟悉前端开发,二者关系很像 Sass
和CSS
的关系.
为什么会有gn
,说是有个叫even
的谷歌负责构建系统的工程师在使用传统的makefile
构建chrome
时觉得太麻烦,不高效,所以设计了一套更简单,更高效新的构建工具gn
+ninja
,然后就被广泛的使用了.
gn语法和配置
gn
有大量的内置变量和库函数,熟悉这些库函数基本就知道gn能干什么,gn的官方文档很齐全.
gn
的语法简单,了解以下几点基本就能看懂gn
代码.重点了解下函数的调用方式,和其他高级语言不太一样.
字符串
a = "mypath"
b = "$a/foo.cc" # b -> "mypath/foo.cc"
c = "foo${a}bar.cc" # c -> "foomypathbar.cc"
列表
a = [ "first" ]
a += [ "second" ] # [ "first", "second" ]
a += [ "third", "fourth" ] # [ "first", "second", "third", "fourth" ]
b = a + [ "fifth" ] # [ "first", "second", "third", "fourth", "fifth" ]
条件语句
if (is_linux || (is_win && target_cpu == "x86")) {sources -= [ "something.cc" ]}else {...}
循环
foreach(i, mylist) {print(i) # Note: i is a copy of each element, not a reference to it.
}
函数调用
print("hello, world")
assert(is_win, "This should only be executed on Windows") # 如果is_win为真,就打印后面的内容
static_library("mylibrary") { sources = [ "a.cc" ]
}
解读:
print
,assert
,static_library
都是库函数,或者叫内置函数.static_library
的调用有点奇怪,它是个函数,函数内部会使用sources
这个内置变量,sources = [ "a.cc" ]
相当于先传参给这个函数的内置变量,并调用这个函数.学习ng得习惯这种语法方式,被大量的使用.
模板 | Templates
gn
提供了很多内置函数,使用偏傻瓜式,若构建不复杂的系统,熟悉这些内置函数,选择填空就可以交作业了,如果想高阶点,想自己定义函数怎么办? 答案是模板,模板就是自定义函数.
#定义模板, 文件路径: //tools/idl_compiler.gni, 后缀.gni 代表这是一个 gn import file
template("idl") { #自定义一个名称为 "idl"的函数source_set(target_name) { #调用内置函数 source_setsources = invoker.sources #invoker为内置变量,含义为调用者内容 即:[ "a", "b" ]的内容}
}
#如何使用模板, 用import,类似 C语言的 #include
import("//tools/idl_compiler.gni")
idl("my_interfaces") { #等同于调用 idlsources = [ "a", "b" ] #给idl传参, 参数的接收方是 invoker.sources
}
明白了模板的使用,阅读鸿蒙gn代码就不会有太大的障碍.
目标项 | Targets
目标是构建图中的一个节点。它通常表示将生成某种可执行文件或库文件。整个构建是由一个个的目标组成.
目标包含:
action: 运行脚本以生成文件
executable: 生成可执行文件
group: 生成依赖关系组
shared_library: 生成.dll或.so动态链接库
static_library: 生成.lib或.a 静态链接库
...
配置项 | Configs
记录完成目标项所需的配置信息,例如:
config("myconfig") {#创建一个标签为`myconfig`的配置项include_dirs = [ "include/common" ]defines = [ "ENABLE_DOOM_MELON" ]}executable("mything") {#生成可执行文件configs = [ ":myconfig" ]#使用标签为`myconfig`的配置项来生成目标文件
}
gn在鸿蒙中的使用
有了以上基础铺垫,正式开始gn
在openharomny
中的使用.
从哪开始
在构建工具篇中已经说清楚了 hb
的python
部分有个工作任务是生成gn
命令所需参数. gn
生成ninja
的命令是 gn gen ...
/home/tools/gn gen /home/openharmony/code-v1.1.1-LTS/out/hispark_aries/ipcamera_hispark_aries \--root=/home/openharmony/code-v1.1.1-LTS \--dotfile=/home/openharmony/code-v1.1.1-LTS/build/lite/.gn \--script-executable=python3 \'--args=ohos_build_type="debug" \ohos_build_compiler_specified="clang" \ohos_build_compiler_dir="/home/tools/llvm" \product_path="/home/openharmony/code-v1.1.1-LTS/vendor/hisilicon/hispark_aries" \device_path="/home/openharmony/code-v1.1.1-LTS/device/hisilicon/hispark_aries/sdk_liteos" \ohos_kernel_type="liteos_a" \enable_ohos_appexecfwk_feature_ability = false \ohos_full_compile=true'
解读
root
,dotfile
,script-executable
是gn内置的固定参数,一切从dotfile
指向的文件开始.即build/lite/.gn
相当于main()
函数的作用,- 打开 build/lite/.gn看下内容,只有两句,先配置好内部参数再工作.
# The location of the build configuration file. #1.完成gn的配置工作buildconfig = "//build/lite/config/BUILDCONFIG.gn" # The source root location. #2.完成gn的编译工作root = "//build/lite"
args
为用户自定义的参数,它们将会在解析BUILD.gn
,BUILDCONFIG.gn
过程中被使用.
BUILDCONFIG.gn | 构建配置项
BUILDCONFIG.gn
为BUILD.gn
做准备,填充好编译所需的配置信息.即生成配置项
详细请查看 build/lite/config/BUILDCONFIG.gn文件全部内容,本篇只贴出部分.
import("//build/lite/ohos_var.gni")
import("${device_path}/config.gni")
....
arch = "arm"
if (ohos_kernel_type == "liteos_a") {target_triple = "$arch-liteos"
} else if (ohos_kernel_type == "linux") {target_triple = "$arch-linux-ohosmusl"
}
...
template("executable") { #生成可执行文件executable(target_name) {forward_variables_from(invoker, Variables_Executable)if (!defined(invoker.deps)) {deps = [ "//build/lite:prebuilts" ]} else {deps += [ "//build/lite:prebuilts" ]}if (defined(invoker.configs)) {configs = []configs += invoker.configs}}
}
set_defaults("executable") {#设置目标类型的默认值configs = default_executable_configsconfigs += [ "//build/lite/config:board_exe_ld_flags" ]
}
...
解读
${device_path}
为命令行参数,本篇为home/openharmony/code-v1.1.1-LTS/device/hisilicon/hispark_aries/sdk_liteos
- 查看构建-配置内容,
BUILDCONFIG
主要任务就是对其中的内置变量赋值.例如:- 指定编译器 clang,
- 如何生成可执行文件的方法等
BUILD.gn | 启动构建
查看 build/lite/BUILD.gn文件,文件注解较多.
#目的是要得到项目各个模块的编译入口
group("ohos") {deps = []if (ohos_build_target == "") {# Step 1: Read product configuration profile.# 第一步:读取配置文件product_path的值来源于根目录的ohos_config.json,如下,内容由 hb set 命令生成# {# "root_path": "/home/openharmony",# "board": "hispark_aries",# "kernel": "liteos_a",# "product": "ipcamera_hispark_aries",# "product_path": "/home/openharmony/vendor/hisilicon/hispark_aries",# "device_path": "/home/openharmony/device/hisilicon/hispark_aries/sdk_liteos",# "patch_cache": null#}product_cfg = read_file("${product_path}/config.json", "json")# Step 2: Loop subsystems configured by product.# 第二步:循环处理各自子系统,config.json中子系统部分格式如下hb#"subsystems": [# {# "subsystem": "aafwk",# "components": [# { "component": "ability", "features":[ "enable_ohos_appexecfwk_feature_ability = false" ] }# ]# },# ...# {# "subsystem": "distributed_schedule",# "components": [# { "component": "system_ability_manager", "features":[] },# { "component": "foundation", "features":[] },# { "component": "distributed_schedule", "features":[] }# ]# },# {# "subsystem": "kernel",# "components": [# { "component": "liteos_a", "features":[] }# ]# },#]foreach(product_configed_subsystem, product_cfg.subsystems) {#对子系统数组遍历操作subsystem_name = product_configed_subsystem.subsystem #读取一个子系统 aafwk,hiviewdfx,security ==subsystem_info = {}# Step 3: Read OS subsystems profile.# 第三步: 读取各个子系统的配置文件subsystem_info =read_file("//build/lite/components/${subsystem_name}.json", "json")# Step 4: Loop components configured by product.# 第四步: 循环读取子系统内各控件的配置信息# 此处以内核为例://build/lite/components/kernel.json"# "components": [# {# "component": "liteos_a", # 组件名称# "description": "liteos-a kernel", # 组件一句话功能描述# "optional": "false", # 组件是否为最小系统必选# "dirs": [ # 组件源码路径# "kernel/liteos_a"# ],# "targets": [ # 组件编译入口# "//kernel/liteos_a:kernel"# ],# "rom": "1.98MB", # 组件ROM值# "ram": "", # 组件RAM估值# "output": [ # 组件编译输出# "liteos.bin"# ],# "adapted_board": [ # 组件已适配的主板# "hispark_aries",# "hispark_taurus",# "hi3518ev300",# "hi3516dv300",# ],# "adapted_kernel": [ "liteos_a" ], # 组件已适配的内核# "features": [], # 组件可配置的特性# "deps": {# "components": [], # 组件依赖的其他组件# "third_party": [ # 组件依赖的三方开源软件# "FreeBSD",# "musl",# "zlib",# "FatFs",# "Linux_Kernel",# "lwip",# "NuttX",# "mtd-utils"# ]# }# },# ]foreach(product_configed_component,product_configed_subsystem.components) { #遍历项目控件数组# Step 5: Check whether the component configured by product is exist.# 第五步: 检查控件配置信息是否存在component_found = false #初始为不存在foreach(system_component, subsystem_info.components) {#项目控件和子系统中的控件遍历对比if (product_configed_component.component ==system_component.component) { #找到了liteos_acomponent_found = true}}#如果没找到的信息,则打印项目控件查找失败日志assert(component_found,"Component \"${product_configed_component.component}\" not found" +", please check your product configuration.")# Step 6: Loop OS components and check validity of product configuration.# 第六步: 检查子系统控件的有效性并遍历控件组,处理各个控件foreach(component, subsystem_info.components) {kernel_valid = false #检查内核board_valid = false #检查开发板# Step 6.1: Skip component which not configured by product.if (component.component == product_configed_component.component) {# Step 6.1.1: Loop OS components adapted kernel type.foreach(component_adapted_kernel, component.adapted_kernel) {if (component_adapted_kernel == product_cfg.kernel_type && kernel_valid == false) { #内核检测是否已适配kernel_valid = true}}# 如果内核未适配,则打印未适配日志assert(kernel_valid,"Invalid component configed, ${subsystem_name}:${product_configed_component.component} " + "not available for kernel: ${product_cfg.kernel_type}!")# Step 6.1.2: Add valid component for compiling.# 添加有效组件进行编译foreach(component_target, component.targets) {//遍历组件的编译入口deps += [ component_target ] #添加到编译列表中}}}}}# Step 7: Add device and product target by default.# 第七步: 添加设备和项目的编译单元# "product_path": "/home/openharmony/vendor/hisilicon/hispark_aries",# "device_path": "/home/openharmony/device/hisilicon/hispark_aries/sdk_liteos",deps += ["${device_path}/../", #添加 //device/hisilicon/hispark_aries 进入编译项"${product_path}" #添加 //vendor/hisilicon/hispark_aries 进入编译项]} else {#编译指定的组件,例如 hb build -T targetA&&targetBdeps += string_split(ohos_build_target, "&&")}
}
解读
- 有三个概念贯彻整个鸿蒙系统,子系统(
subsystems
),组件(components
),功能(features
).理解它们的定位和特点是解读鸿蒙的关键所在. - 先找到
product_path
下的 配置文件config.json
,里面配置了项目所要使用的子系统和组件. - 再遍历项目所使用的组件是否能再
//build/lite/components/*.json
组件集中能找到. - 将找到的组件
targets
加入到编译列表deps
中.targets
指向了要编译的组件目录.
import("//build/lite/config/component/lite_component.gni") #组件模板函数import("//build/lite/config/subsystem/lite_subsystem.gni") #子系统模板函数lite_subsystem("kernel") {#编译内核子系统/组件入口subsystem_components = []if (enable_ohos_kernel_liteos_a_ext_build == false) {subsystem_components += ["//kernel/liteos_a/kernel","//kernel/liteos_a/net","//kernel/liteos_a/lib","//kernel/liteos_a/compat","//kernel/liteos_a/fs","//kernel/liteos_a/arch:platform_cpu",]if (LOSCFG_SHELL) {subsystem_components += [ "//kernel/liteos_a/shell" ]}} else {deps = [ ":make" ]}}
lite_subsystem
是个模板函数(自定义函数),它的目的只有一个填充 deps,deps
是私有链接依赖关系,最终会形成一颗依赖树.gn会根据这些依赖关系生成最终的.ninja文件.
# 定义一个子系统# lite_subsystem template模板定义了子系统中包含的所有模块# 参数# subsystem_components (必须))# [范围列表] 定义子系统的所有模块.template("lite_subsystem") {assert(defined(invoker.subsystem_components), "subsystem_components in required.")lite_subsystem_components = invoker.subsystem_componentsgroup(target_name) {deps = []if(defined(invoker.deps)) {deps += invoker.deps}# add subsystem packagesforeach(pkg_label, lite_subsystem_components) {deps += [ pkg_label ]}}}
生成了哪些文件
执行后gn gen
会生成如下文件和目录
turing@ubuntu:/home/openharmony/code-v1.1.1-LTS/out/hispark_aries/ipcamera_hispark_aries$ ls
args.gn build.ninja build.ninja.d NOTICE_FILE obj test_info toolchain.ninja
build.ninja.d
中记录依赖的 BUILD.gn
文件路径
build.ninja: ../../../base/global/resmgr_lite/frameworks/resmgr_lite/BUILD.gn \../../../base/hiviewdfx/hilog_lite/frameworks/featured/BUILD.gn \../../../base/hiviewdfx/hilog_lite/services/apphilogcat/BUILD.gn \....
gn
根据这些组件的BUILD.gn
在obj
目录下对应生成了每个组件的.ninja
文件.此处列出鸿蒙L1所有的 .ninja
文件, 具体ninja
是如何编译成最终的库和可执行文件的,将在后续篇中详细介绍其语法和应用.
turing@ubuntu:/home/openharmony/code-v1.1.1-LTS/out/hispark_aries/ipcamera_hispark_aries/obj$ tree
├── base
│ ├── global
│ │ └── resmgr_lite
│ │ └── frameworks
│ │ └── resmgr_lite
│ │ └── global_resmgr.ninja
│ ├── hiviewdfx
│ │ └── hilog_lite
│ │ ├── frameworks
│ │ │ └── featured
│ │ │ ├── hilog_shared.ninja
│ │ │ └── hilog_static.ninja
│ │ └── services
│ │ ├── apphilogcat
│ │ │ ├── apphilogcat.ninja
│ │ │ └── apphilogcat_static.ninja
│ │ └── hilogcat
│ │ ├── hilogcat.ninja
│ │ └── hilogcat_static.ninja
│ ├── security
│ │ ├── appverify
│ │ │ └── interfaces
│ │ │ └── innerkits
│ │ │ └── appverify_lite
│ │ │ ├── products
│ │ │ │ └── ipcamera
│ │ │ │ └── verify_base.ninja
│ │ │ ├── unittest
│ │ │ │ └── app_verify_test.ninja
│ │ │ └── verify.ninja
│ │ ├── deviceauth
│ │ │ └── frameworks
│ │ │ └── deviceauth_lite
│ │ │ └── source
│ │ │ └── hichainsdk.ninja
│ │ ├── huks
│ │ │ └── frameworks
│ │ │ └── huks_lite
│ │ │ └── source
│ │ │ └── huks.ninja
│ │ └── permission
│ │ └── services
│ │ └── permission_lite
│ │ ├── ipc_auth
│ │ │ └── ipc_auth_target.ninja
│ │ ├── pms
│ │ │ └── pms_target.ninja
│ │ ├── pms_base
│ │ │ └── pms_base.ninja
│ │ └── pms_client
│ │ └── pms_client.ninja
│ └── startup
│ ├── appspawn_lite
│ │ └── services
│ │ ├── appspawn.ninja
│ │ └── test
│ │ └── unittest
│ │ └── common
│ │ └── appspawn_test.ninja
│ ├── bootstrap_lite
│ │ └── services
│ │ └── source
│ │ └── bootstrap.ninja
│ ├── init_lite
│ │ └── services
│ │ ├── init.ninja
│ │ └── test
│ │ └── unittest
│ │ └── common
│ │ └── init_test.ninja
│ └── syspara_lite
│ └── frameworks
│ ├── parameter
│ │ └── src
│ │ └── sysparam.ninja
│ ├── token
│ │ └── token_shared.ninja
│ └── unittest
│ └── parameter
│ └── ParameterTest.ninja
├── build
│ └── lite
│ └── config
│ └── component
│ ├── cJSON
│ │ ├── cjson_shared.ninja
│ │ └── cjson_static.ninja
│ ├── openssl
│ │ ├── openssl_shared.ninja
│ │ └── openssl_static.ninja
│ └── zlib
│ ├── zlib_shared.ninja
│ └── zlib_static.ninja
├── drivers
│ ├── adapter
│ │ └── uhdf
│ │ ├── manager
│ │ │ └── hdf_core.ninja
│ │ ├── platform
│ │ │ └── hdf_platform.ninja
│ │ ├── posix
│ │ │ └── hdf_posix_osal.ninja
│ │ └── test
│ │ └── unittest
│ │ ├── common
│ │ │ └── hdf_test_common.ninja
│ │ ├── config
│ │ │ └── hdf_adapter_uhdf_test_config.ninja
│ │ ├── manager
│ │ │ ├── hdf_adapter_uhdf_test_door.ninja
│ │ │ ├── hdf_adapter_uhdf_test_ioservice.ninja
│ │ │ ├── hdf_adapter_uhdf_test_manager.ninja
│ │ │ └── hdf_adapter_uhdf_test_sbuf.ninja
│ │ ├── osal
│ │ │ └── hdf_adapter_uhdf_test_osal.ninja
│ │ └── platform
│ │ └── hdf_adapter_uhdf_test_platform.ninja
│ └── peripheral
│ ├── input
│ │ └── hal
│ │ └── hdi_input.ninja
│ └── wlan
│ ├── client
│ │ └── wifi_driver_client.ninja
│ ├── hal
│ │ └── wifi_hal.ninja
│ └── test
│ ├── performance
│ │ └── hdf_peripheral_wlan_test_performance.ninja
│ └── unittest
│ └── hdf_peripheral_wlan_test.ninja
├── foundation
│ ├── aafwk
│ │ └── aafwk_lite
│ │ ├── frameworks
│ │ │ ├── ability_lite
│ │ │ │ └── ability.ninja
│ │ │ ├── abilitymgr_lite
│ │ │ │ └── abilitymanager.ninja
│ │ │ └── want_lite
│ │ │ └── want.ninja
│ │ └── services
│ │ └── abilitymgr_lite
│ │ ├── abilityms.ninja
│ │ ├── tools
│ │ │ └── aa.ninja
│ │ └── unittest
│ │ └── test_lv0
│ │ └── page_ability_test
│ │ └── ability_test_pageAbilityTest_lv0.ninja
│ ├── ai
│ │ └── engine
│ │ ├── services
│ │ │ ├── client
│ │ │ │ ├── ai_client.ninja
│ │ │ │ ├── client_executor
│ │ │ │ │ └── client_executor.ninja
│ │ │ │ └── communication_adapter
│ │ │ │ └── ai_communication_adapter.ninja
│ │ │ ├── common
│ │ │ │ ├── platform
│ │ │ │ │ ├── dl_operation
│ │ │ │ │ │ └── dlOperation.ninja
│ │ │ │ │ ├── event
│ │ │ │ │ │ └── event.ninja
│ │ │ │ │ ├── lock
│ │ │ │ │ │ └── lock.ninja
│ │ │ │ │ ├── os_wrapper
│ │ │ │ │ │ └── ipc
│ │ │ │ │ │ └── aie_ipc.ninja
│ │ │ │ │ ├── semaphore
│ │ │ │ │ │ └── semaphore.ninja
│ │ │ │ │ ├── threadpool
│ │ │ │ │ │ └── threadpool.ninja
│ │ │ │ │ └── time
│ │ │ │ │ └── time.ninja
│ │ │ │ ├── protocol
│ │ │ │ │ └── data_channel
│ │ │ │ │ └── data_channel.ninja
│ │ │ │ └── utils
│ │ │ │ └── encdec
│ │ │ │ └── encdec.ninja
│ │ │ └── server
│ │ │ ├── ai_server.ninja
│ │ │ ├── communication_adapter
│ │ │ │ └── ai_communication_adapter.ninja
│ │ │ ├── plugin_manager
│ │ │ │ └── plugin_manager.ninja
│ │ │ └── server_executor
│ │ │ └── server_executor.ninja
│ │ └── test
│ │ ├── common
│ │ │ ├── ai_test_common.ninja
│ │ │ └── dl_operation
│ │ │ └── dl_operation_so
│ │ │ └── dlOperationSo.ninja
│ │ ├── function
│ │ │ ├── ai_test_function.ninja
│ │ │ └── death_callback
│ │ │ ├── testDeathCallbackLibrary.ninja
│ │ │ └── testDeathCallback.ninja
│ │ ├── performance
│ │ │ └── ai_test_performance_unittest.ninja
│ │ └── sample
│ │ ├── asyncDemoPluginCode.ninja
│ │ ├── sample_plugin_1.ninja
│ │ ├── sample_plugin_2.ninja
│ │ └── syncDemoPluginCode.ninja
│ ├── appexecfwk
│ │ └── appexecfwk_lite
│ │ ├── frameworks
│ │ │ └── bundle_lite
│ │ │ └── bundle.ninja
│ │ └── services
│ │ └── bundlemgr_lite
│ │ ├── bundle_daemon
│ │ │ └── bundle_daemon.ninja
│ │ ├── bundlems.ninja
│ │ └── tools
│ │ └── bm.ninja
│ ├── communication
│ │ ├── ipc_lite
│ │ │ └── liteipc_adapter.ninja
│ │ └── softbus_lite
│ │ └── softbus_lite.ninja
│ ├── distributedschedule
│ │ ├── dmsfwk_lite
│ │ │ ├── dmslite.ninja
│ │ │ └── moduletest
│ │ │ └── dtbschedmgr_lite
│ │ │ └── distributed_schedule_test_dms.ninja
│ │ ├── safwk_lite
│ │ │ └── foundation.ninja
│ │ └── samgr_lite
│ │ ├── communication
│ │ │ └── broadcast
│ │ │ └── broadcast.ninja
│ │ ├── samgr
│ │ │ ├── adapter
│ │ │ │ └── samgr_adapter.ninja
│ │ │ ├── samgr.ninja
│ │ │ └── source
│ │ │ └── samgr_source.ninja
│ │ ├── samgr_client
│ │ │ └── client.ninja
│ │ ├── samgr_endpoint
│ │ │ ├── endpoint_source.ninja
│ │ │ └── store_source.ninja
│ │ └── samgr_server
│ │ └── server.ninja
│ ├── graphic
│ │ ├── surface
│ │ │ ├── surface.ninja
│ │ │ └── test
│ │ │ └── lite_surface_unittest.ninja
│ │ ├── ui
│ │ │ └── ui.ninja
│ │ ├── utils
│ │ │ ├── graphic_hals.ninja
│ │ │ ├── graphic_utils.ninja
│ │ │ └── test
│ │ │ ├── graphic_test_color.ninja
│ │ │ ├── graphic_test_container.ninja
│ │ │ ├── graphic_test_geometry2d.ninja
│ │ │ ├── graphic_test_math.ninja
│ │ │ └── graphic_test_style.ninja
│ │ └── wms
│ │ ├── wms_client.ninja
│ │ └── wms_server.ninja
│ └── multimedia
│ ├── audio_lite
│ │ └── frameworks
│ │ └── audio_capturer_lite.ninja
│ ├── camera_lite
│ │ └── frameworks
│ │ └── camera_lite.ninja
│ ├── media_lite
│ │ ├── frameworks
│ │ │ ├── player_lite
│ │ │ │ └── player_lite.ninja
│ │ │ └── recorder_lite
│ │ │ └── recorder_lite.ninja
│ │ ├── interfaces
│ │ │ └── kits
│ │ │ └── player_lite
│ │ │ └── js
│ │ │ └── builtin
│ │ │ └── audio_lite_api.ninja
│ │ └── services
│ │ └── media_server.ninja
│ └── utils
│ └── lite
│ └── media_common.ninja
├── test
│ ├── developertest
│ │ ├── examples
│ │ │ └── lite
│ │ │ └── cxx_demo
│ │ │ └── test
│ │ │ └── unittest
│ │ │ └── common
│ │ │ └── CalcSubTest.ninja
│ │ └── third_party
│ │ └── lib
│ │ └── cpp
│ │ ├── gtest_main.ninja
│ │ └── gtest.ninja
│ └── xts
│ ├── acts
│ │ ├── aafwk_lite
│ │ │ └── ability_posix
│ │ │ └── module_ActsAbilityMgrTest.ninja
│ │ ├── ai_lite
│ │ │ └── ai_engine_posix
│ │ │ └── base
│ │ │ ├── module_ActsAiEngineTest.ninja
│ │ │ └── src
│ │ │ └── sample
│ │ │ ├── asyncDemoPluginCode.ninja
│ │ │ ├── sample_plugin_1_sync.ninja
│ │ │ ├── sample_plugin_2_async.ninja
│ │ │ └── syncDemoPluginCode.ninja
│ │ ├── appexecfwk_lite
│ │ │ └── bundle_mgr_posix
│ │ │ └── module_ActsBundleMgrTest.ninja
│ │ ├── communication_lite
│ │ │ ├── lwip_posix
│ │ │ │ └── module_ActsLwipTest.ninja
│ │ │ └── softbus_posix
│ │ │ └── module_ActsSoftBusTest.ninja
│ │ ├── distributed_schedule_lite
│ │ │ └── samgr_posix
│ │ │ └── module_ActsSamgrTest.ninja
│ │ ├── graphic_lite
│ │ │ ├── graphic_utils
│ │ │ │ ├── a
│ │ │ │ │ └── module_ActsUiInterfaceTest1.ninja
│ │ │ │ ├── color_posix
│ │ │ │ │ └── module_ActsColorTest.ninja
│ │ │ │ ├── geometry2d_posix
│ │ │ │ │ └── module_ActsGeometyr2dTest.ninja
│ │ │ │ ├── graphic_math_posix
│ │ │ │ │ └── module_ActsGraphicMathTest.ninja
│ │ │ │ ├── heap_base_posix
│ │ │ │ │ └── module_ActsHeapBaseTest.ninja
│ │ │ │ ├── list_posix
│ │ │ │ │ └── module_ActsListTest.ninja
│ │ │ │ ├── mem_api_posix
│ │ │ │ │ └── module_ActsGraphMemApiTest.ninja
│ │ │ │ ├── rect_posix
│ │ │ │ │ └── module_ActsRectTest.ninja
│ │ │ │ ├── transform_posix
│ │ │ │ │ └── module_ActsTransformTest.ninja
│ │ │ │ └── version_posix
│ │ │ │ └── module_ActsGraphVersionTest.ninja
│ │ │ ├── surface
│ │ │ │ └── surface_posix
│ │ │ │ └── module_ActsSurfaceTest.ninja
│ │ │ └── ui
│ │ │ ├── a
│ │ │ │ └── module_ActsUiInterfaceTest.ninja
│ │ │ ├── animator_posix
│ │ │ │ └── module_ActsAnimatorTest.ninja
│ │ │ ├── easing_equation_posix
│ │ │ │ └── module_ActsEasingEquationTest.ninja
│ │ │ ├── events_posix
│ │ │ │ └── module_ActsEventsTest.ninja
│ │ │ ├── flexlayout_posix
│ │ │ │ └── module_ActsFlexlaoutTest.ninja
│ │ │ ├── gridlayout_posix
│ │ │ │ └── module_ActsGridLayoutTest.ninja
│ │ │ ├── image_posix
│ │ │ │ └── module_ActsImageTest.ninja
│ │ │ ├── interpolation_posix
│ │ │ │ └── module_ActsInterpoliationTest.ninja
│ │ │ ├── layout_posix
│ │ │ │ └── module_ActsLayoutTest.ninja
│ │ │ ├── listlayout_posix
│ │ │ │ └── module_ActsListlayoutTest.ninja
│ │ │ ├── screen_posix
│ │ │ │ └── module_ActsScreenTest.ninja
│ │ │ ├── style_posix
│ │ │ │ └── module_ActsStyleTest.ninja
│ │ │ ├── theme_posix
│ │ │ │ └── module_ActsThemeTest.ninja
│ │ │ ├── ui_abstract_progress_posix
│ │ │ │ └── module_ActsUIAbstractProgressTest.ninja
│ │ │ ├── ui_analog_clock_posix
│ │ │ │ └── module_ActsUIAnalogClockTest.ninja
│ │ │ ├── uianimator_posix
│ │ │ │ └── module_ActsUIAnimatorTest.ninja
│ │ │ ├── ui_arc_lable_posix
│ │ │ │ └── module_ActsUIArcLabelTest.ninja
│ │ │ ├── ui_axis_posix
│ │ │ │ └── module_ActsUIAxisTest.ninja
│ │ │ ├── ui_box_porgress_posix
│ │ │ │ └── module_ActsUIBoxProgressTest.ninja
│ │ │ ├── ui_button_posix
│ │ │ │ └── module_ActsUIButtonTest.ninja
│ │ │ ├── ui_canvas_posix
│ │ │ │ └── module_ActsUICanvasTest.ninja
│ │ │ ├── ui_chart_posix
│ │ │ │ └── module_ActsUIChartTest.ninja
│ │ │ ├── ui_checbox_posix
│ │ │ │ └── module_ActsUICheckboxTest.ninja
│ │ │ ├── ui_circle_progress_posix
│ │ │ │ └── module_ActsUICircleProgressTest.ninja
│ │ │ ├── ui_digital_clock_posix
│ │ │ │ └── module_ActsUIDigitalClockTest.ninja
│ │ │ ├── ui_image_animator_posix
│ │ │ │ └── module_ActsUIImageAnimatorTest.ninja
│ │ │ ├── ui_image_posix
│ │ │ │ └── module_ActsUIImageTest.ninja
│ │ │ ├── ui_label_button_posix
│ │ │ │ └── module_ActsUILabelButtonTest.ninja
│ │ │ ├── ui_label_posix
│ │ │ │ └── module_ActsUILabelTest.ninja
│ │ │ ├── ui_list_posix
│ │ │ │ └── module_ActsUIListTest.ninja
│ │ │ ├── ui_picker_posix
│ │ │ │ └── module_ActsUIPickerTest.ninja
│ │ │ ├── ui_radio_button_posix
│ │ │ │ └── module_ActsUIRadioButtonTest.ninja
│ │ │ ├── ui_repeat_button_posix
│ │ │ │ └── module_ActsUIRepeatButtonTest.ninja
│ │ │ ├── ui_screenshot_posix
│ │ │ │ └── module_ActsUIScreenshotTest.ninja
│ │ │ ├── ui_scroll_view_posix
│ │ │ │ └── module_ActsUIScrollViewTest.ninja
│ │ │ ├── ui_slider_posix
│ │ │ │ └── module_ActsUISliderTest.ninja
│ │ │ ├── ui_surface_view_posix
│ │ │ │ └── module_ActsUISurfaceViewTest.ninja
│ │ │ ├── ui_swipe_view_posix
│ │ │ │ └── module_ActsUISwipeViewTest.ninja
│ │ │ ├── ui_text_posix
│ │ │ │ └── module_ActsUITextTest.ninja
│ │ │ ├── ui_texture_mapper_posix
│ │ │ │ └── module_ActsUITextureMapperTest.ninja
│ │ │ ├── ui_time_picker_posix
│ │ │ │ └── module_ActsUITimePickerTest.ninja
│ │ │ ├── ui_toggle_button_posix
│ │ │ │ └── module_ActsUIToggleButtonTest.ninja
│ │ │ ├── ui_view_group_posix
│ │ │ │ └── module_ActsUIViewGroupTest.ninja
│ │ │ └── ui_view_posix
│ │ │ └── module_ActsUIViewTest.ninja
│ │ ├── hiviewdfx_lite
│ │ │ └── hilog_posix
│ │ │ └── module_ActsHilogTest.ninja
│ │ ├── kernel_lite
│ │ │ ├── dyload_posix
│ │ │ │ └── module_ActsDyloadTest.ninja
│ │ │ ├── fs_posix
│ │ │ │ ├── jffs
│ │ │ │ │ └── module_ActsJFFS2Test.ninja
│ │ │ │ ├── nfs
│ │ │ │ │ └── module_ActsNFSTest.ninja
│ │ │ │ ├── vfat
│ │ │ │ │ └── module_ActsVFATTest.ninja
│ │ │ │ └── vfat_storage
│ │ │ │ └── module_ActsVFATstorageTest.ninja
│ │ │ ├── futex_posix
│ │ │ │ └── module_ActsFutexApiTest.ninja
│ │ │ ├── io_posix
│ │ │ │ └── module_ActsIoApiTest.ninja
│ │ │ ├── ipc_posix
│ │ │ │ ├── message_queue
│ │ │ │ │ └── module_ActsIpcMqTest.ninja
│ │ │ │ ├── pipe_fifo
│ │ │ │ │ └── module_ActsIpcPipeTest.ninja
│ │ │ │ ├── semaphore
│ │ │ │ │ └── module_ActsIpcSemTest.ninja
│ │ │ │ ├── shared_memory
│ │ │ │ │ └── module_ActsIpcShmTest.ninja
│ │ │ │ └── signal
│ │ │ │ └── module_ActsIpcSignalTest.ninja
│ │ │ ├── math_posix
│ │ │ │ ├── complexTest.ninja
│ │ │ │ └── module_ActsMathApiTest.ninja
│ │ │ ├── mem_posix
│ │ │ │ └── module_ActsMemApiTest.ninja
│ │ │ ├── net_posix
│ │ │ │ └── module_ActsNetTest.ninja
│ │ │ ├── process_posix
│ │ │ │ └── module_ActsProcessApiTest.ninja
│ │ │ ├── sched_posix
│ │ │ │ └── module_ActsSchedApiTest.ninja
│ │ │ ├── sys_posix
│ │ │ │ └── module_ActsSysApiTest.ninja
│ │ │ ├── time_posix
│ │ │ │ └── module_ActsTimeApiTest.ninja
│ │ │ ├── util_posix
│ │ │ │ └── module_ActsUtilApiTest.ninja
│ │ │ └── utils
│ │ │ ├── libfs.ninja
│ │ │ ├── libmt_utils.ninja
│ │ │ └── libutils.ninja
│ │ ├── multimedia_lite
│ │ │ └── media_lite_posix
│ │ │ └── recorder_native
│ │ │ └── module_ActsMediaRecorderTest.ninja
│ │ ├── security_lite
│ │ │ ├── datahuks_posix
│ │ │ │ └── module_ActsSecurityDataTest.ninja
│ │ │ └── permission_posix
│ │ │ ├── capability
│ │ │ │ ├── capability_shared.ninja
│ │ │ │ ├── jffs
│ │ │ │ │ └── module_ActsJFFS2CapabilityTest.ninja
│ │ │ │ └── vfat
│ │ │ │ └── module_ActsVFATCapabilityTest.ninja
│ │ │ ├── dac
│ │ │ │ ├── jffs
│ │ │ │ │ └── module_ActsJFFS2DACTest.ninja
│ │ │ │ └── vfat
│ │ │ │ └── module_ActsVFATDACTest.ninja
│ │ │ └── pms
│ │ │ └── module_ActsPMSTest.ninja
│ │ ├── startup_lite
│ │ │ ├── bootstrap_posix
│ │ │ │ └── module_ActsBootstrapTest.ninja
│ │ │ └── syspara_posix
│ │ │ └── module_ActsParameterTest.ninja
│ │ └── utils_lite
│ │ └── kv_store_posix
│ │ └── module_ActsKvStoreTest.ninja
│ └── tools
│ └── lite
│ ├── hcpptest
│ │ ├── gmock_main.ninja
│ │ ├── gmock.ninja
│ │ ├── hcpptest_main.ninja
│ │ └── hcpptest.ninja
│ └── others
│ └── query
│ └── query.ninja
├── third_party
│ ├── bounds_checking_function
│ │ ├── libsec_shared.ninja
│ │ └── libsec_static.ninja
│ ├── freetype
│ │ └── freetype.ninja
│ ├── giflib
│ │ └── libgif.ninja
│ ├── iniparser
│ │ └── iniparser.ninja
│ ├── libjpeg
│ │ └── libjpeg.ninja
│ ├── libpng
│ │ └── libpng.ninja
│ ├── mbedtls
│ │ ├── mbedtls_gt.ninja
│ │ ├── mbedtls_shared.ninja
│ │ └── mbedtls_static.ninja
│ └── qrcodegen
│ └── qrcodegen.ninja
├── utils
│ └── native
│ └── lite
│ ├── kv_store
│ │ └── src
│ │ └── utils_kv_store.ninja
│ └── os_dump
│ └── os_dump.ninja
└── vendor└── hisilicon└── hispark_aries└── hals├── security│ └── permission_lite│ └── hal_pms.ninja└── utils├── sys_param│ └── hal_sysparam.ninja└── token└── haltoken_shared.ninja
写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请移步前往