ArkUI-X Project Code Structure and Building
Background
ArkUI is the default development framework of OpenHarmony. In the ArkUI-X project, a set of code needs to support build across different OS platforms. Therefore, the ArkUI-X project shares code repositories with OpenHarmony, and some repositories directly point to OpenHarmony related repositories.
Code and Repository Structure
The directory structure of the code project is as follows:
├── arkcompiler // Ark compiler
├── base // Basic capabilities
├── build // Project build and configuration scripts
├── build_plugins // Cross-platform build plug-ins
├── commonlibrary // Common libraries
├── community // Community-related information
├── developtools // Developer tools
├── docs // Related documents
├── foundation
│ ├── appframework // Application framework compatibility adaptation layer
│ ├── arkui // ArkUI engines
│ ├── communication // Communication capability
│ ├── distributeddatamgr // Distributed data management
│ ├── filemanagement // File management
│ ├── graphic // Graphics engine
│ └── multimedia // Multimedia
├── interface // Interface declaration
├── plugins // Plug-in management and implementation
├── prebuilts // Directory for prebuilts
├── productdefine // Product configuration
├── samples // Sample code
├── samples // Test framework and cases
└── third_party // Third-party libraries
The table below lists the code repositories.
| Directory | Description | Code Repository |
|---|---|---|
| build | Project build and configuration scripts | OpenHarmony/build |
| build_plugins | Cross-platform build plug-ins | ArkUI-X/build_plugins |
| samples | Application samples | ArkUI-X/samples |
| community | Community operations and management | ArkUI-X/community |
| docs | Reference documents | ArkUI-X/docs |
| interface/sdk | ArkUI-X SDK configuration | ArkUI-X/interface_sdk |
| plugins | API plug-in management and OpenHarmony API plug-in implementation | ArkUI-X/plugins |
| test/xts | ArkUI-X cross-platform application test suites | ArkUI-X/xts |
| test/testfwk/arkxtest | ArkUI-X test framework | ArkUI-X/arkxtest |
| developtools/ace_tools | Cross-platform CLI tool | ArkUI-X/cli |
| foundation/appframework | Application framework compatibility adaptation | ArkUI-X/app_framework |
| foundation/arkui/ace_engine/adapter/android | Android platform adaptation code | ArkUI-X/arkui_for_android |
| foundation/arkui/ace_engine/adapter/ios | iOS platform adaptation code | ArkUI-X/arkui_for_ios |
| foundation/arkui/ace_engine | Core code of the ArkUI engine | OpenHarmony/arkui_ace_engine |
| foundation/arkui/napi | Native API extension mechanism | OpenHarmony/arkui_napi |
| foundation/communication/netmanager_base | Network management module | OpenHarmony/communication_netmanager_base |
| foundation/communication/netstack | Network protocol stack | OpenHarmony/communication_netstack |
| foundation/graphic/graphic_2d | Basic 2D graphics library | OpenHarmony/graphic_graphic_2d |
| foundation/filemanagement/file_api | APIs for accessing folders and files | OpenHarmony/filemanagement_file_api |
| foundation/multimedia/image_framework | Code for implementing image encoding and decoding | OpenHarmony/multimedia_image_framework |
| developtools/ace_ets2bundle | Compilation tool and cross-platform application build tool using the ArkTS-based declarative development paradigm | OpenHarmony/ace_ets2bundle |
| developtools/ace_js2bundle | Compilation tool and cross-platform application building tool using the JS-compatible web-like development paradigm | OpenHarmony/ace_js2bundle |
| arkcompiler/ets_frontend | Ark frontend tool | OpenHarmony/arkcompiler_ets_frontend |
| arkcompiler/ets_runtime | Ark ArkTS runtime | OpenHarmony/arkcompiler_ets_runtime |
| arkcompiler/runtime_core | Ark compiler runtime | OpenHarmony/arkcompiler_runtime_core |
| arkcompiler/toolchain | Debugging and tuning tool | OpenHarmony/arkcompiler_toolchain |
| prebuilts | Directory for prebuilts (Python, nodejs, clang, and cmake) | Pre-download the software using a script. |
| third_party | Open-source third-party components (reuse the OpenHarmony code repositories) | Open-source third-party library collection referenced. |
| commonlibrary/c_utils | Common C++ functions and classes | OpenHarmony/commonlibrary_c_utils |
| commonlibrary/ets_utils | Basic JS APIs, such as APIs for managing URLs and URIs | OpenHarmony/commonlibrary_ets_utils |
| base/hiviewdfx/hilog | System logging | OpenHarmony/hiviewdfx_hilog |
| base/web/webview | Native engine of the WebView component | OpenHarmony/web_webview |
| base/global/resource_management | Global resource management | OpenHarmony/global_resource_management |
Release Synchronization Policy
The OpenHarmony-related code repositories point to the fixed tag points of the OpenHarmony master repository and are synchronized periodically. By default, the synchronization is performed based on the weekly branch frequency of the OpenHarmony.
ace_engine Directory Structure
The directory structure of the ArkUI engine core code repository ace_engine is as follows:
foundation/arkui/ace_engine
├── ace_config.gni // Global configuration file
├── adapter // Platform adaptation layer
│ ├── android // Independent repository for Android adaptation
│ │ ├── build
│ │ ├── capability
│ │ ├── entrance
│ │ ├── stage
│ │ └── osal
│ ├── ios // Independent repository for iOS adaptation
│ │ ├── build
│ │ ├── capability
│ │ ├── entrance
│ │ ├── stage
│ │ └── osal
│ ├── ohos // OpenHarmony platform adaptation
│ └── preview // Previewer adaptation with the platform
├── build // Build configuration
│ ├── ace_gen_obj.gni
│ ├── ace_lib.gni
│ ├── BUILD.gn
│ ├── search.py
│ └── tools
├── BUILD.gn // Global build configuration
├── frameworks // Engine framework layer
│ ├── base // base library
│ ├── bridge // Frontend bridging
│ └── core // Engine core implementation
├── interfaces // Universal external interfaces
│ └── napi
│ └── kits
├── LICENSE
├── OAT.xml
├── README.md
├── README_zh.md
└── test // Test code
Compilation and Build Process
To support cross-platform build with a set of code, the compilation configuration needs to be dynamically adjusted based on the code structure. Since different OS platforms have different dependencies and the source code of the dependencies may vary with the environment, the build targets must be dynamically defined.
-
Build entry: The build entry of OpenHarmony is bundle.json. The bundle.json file defines the subsystem components and external interfaces and stored in the root directory of the subsystem. The other OS platforms use the module name ace_packages as the build entry.
-
Global configuration: The BUILD.gn and ace_config.gni files in the root directory contain global configurations. BUILD.gn defines ace_config and ace_test_config used globally. The ace_config.gni file defines the following configurations:
- Configuration of global variables, for example, enable_ace_debug.
- Global path definition, for example, ace_napi.
- Configuration of the toolchain, for example, windows_buildtool.
- Definition of global macros used in ace_config, for example, ace_common_defines.
- Platform-related configuration ace_platforms, which is the key to dynamic definition of the build targets. The code is as follows:
ace_platforms = [] # Search for directories under adapter and generate all adapter directory names. _ace_adapter_dir = rebase_path("$ace_root/adapter", root_build_dir) _adapters = exec_script("build/search.py", [ _ace_adapter_dir ], "list lines") # Import the platform.gni file of each adapter, generate the platform definition configuration, and add the configuration to the ace_platforms file. foreach(item, _adapters) { import_var = {} import_var = { import("$ace_root/adapter/$item/build/platform.gni") } if (defined(import_var.platforms)) { foreach(platform, import_var.platforms) { if (defined(platform.name)) { ace_platforms += [ platform ] } } } } -
Platform configuration: The build directory of each adapter contains platform-related configuration.
├── BUILD.gn // Definition of the entry target, for example, "ace_packages" ├── config.gni // Platform configuration ├── bundle.json // Component configuration, which is required only for OpenHarmony └── platform.gni // Platform definitionThe content of a config.gni file is similar to the following:
defines = [ "OHOS_PLATFORM", "OHOS_STANDARD_SYSTEM", ] js_engines = [] ark_engine = { engine_name = "ark" engine_path = "jsi" engine_defines = [ "USE_ARK_ENGINE" ] } js_engines += [ ark_engine ] disable_gpu = true use_external_icu = "shared" use_curl_download = true ohos_standard_fontmgr = true sk_use_hilog = true accessibility_support = false rich_components_support = true advance_components_support = false form_components_support = false if (disable_gpu) { defines += [ "GPU_DISABLED" ] } cflags_cc = [ "-Wno-thread-safety-attributes", "-Wno-thread-safety-analysis", ] platform_deps = [ "//foundation/arkui/ace_engine/adapter/ohos/entrance:ace_ohos_standard_entrance", "//foundation/arkui/ace_engine/adapter/ohos/osal:ace_osal_ohos", ]This file defines all differentiated configurations of the platform, such as macros, cflags, platform-specific dependencies, and some functional switches. In specific module definitions, the configuration such as macros and cflags are directly imported from config.gni. Other differences must be defined as functional switches, such as use_curl_download, to make the definitions of module gn and features clearer.
-
Dynamic target definition: Dynamic target definition can be implemented based on the previous platform configuration. The following uses the base module as an example:
import("//build/ohos.gni") import("//foundation/arkui/ace_engine/ace_config.gni") template("ace_base_source_set") { forward_variables_from(invoker, "*") ohos_source_set(target_name) { # Import define and cflags from the platform config. defines += invoker.defines cflags_cc = [] cflags_cc += invoker.cflags_cc deps = [ "$ace_root/build/third_party/cJSON:third_party_cjson", "i18n:ace_base_i18n_$platform", "resource:ace_resource", ] configs = [ "$ace_root:ace_config" ] # add base source file here sources = [ "geometry/animatable_dimension.cpp", "geometry/animatable_matrix4.cpp", "geometry/matrix4.cpp", "geometry/quaternion.cpp", "geometry/transform_util.cpp", "json/json_util.cpp", "log/ace_trace.cpp", "log/dump_log.cpp", "memory/memory_monitor.cpp", "thread/background_task_executor.cpp", "utils/base_id.cpp", "utils/date_util.cpp", "utils/resource_configuration.cpp", "utils/string_utils.cpp", "utils/time_util.cpp", ] # Perform differentiated configuration via platform variables. if (platform != "windows") { # add secure c API include_dirs = [ "//utils/native/base/include" ] sources += [ "//utils/native/base/src/securec/memset_s.c", "//utils/native/base/src/securec/securecutil.c", "//utils/native/base/src/securec/secureprintoutput_a.c", "//utils/native/base/src/securec/snprintf_s.c", "//utils/native/base/src/securec/sprintf_s.c", "//utils/native/base/src/securec/strcat_s.c", "//utils/native/base/src/securec/strcpy_s.c", "//utils/native/base/src/securec/vsnprintf_s.c", "//utils/native/base/src/securec/vsprintf_s.c", ] } # Determine whether to depend on and compile curl based on the platform config. if (defined(config.use_curl_download) && config.use_curl_download) { configs += [ "//third_party/curl:curl_config" ] sources += [ "$ace_root/frameworks/base/network/download_manager.cpp" ] deps += [ "//third_party/curl:curl" ] } } } # Dynamically define targets based on ace_platforms. For example, if ace_platforms are ohos, windows, and mac, three targets, # namely ace_base_ohos, ace_base_windows, and ace_base_mac, will be defined. foreach(item, ace_platforms) { ace_base_source_set("ace_base_" + item.name) { # Import variables from platform platform = item.name defines = [] cflags_cc = [] config = { } if (defined(item.config)) { config = item.config } if (defined(config.defines)) { defines = config.defines } if (defined(config.cflags_cc)) { cflags_cc = config.cflags_cc } } } -
Module definition: Divide modules based on the directory structure and define each module clearly. Use features to differentiate internal differences of a platform. For inter-platform differences, use the preceding method to define modules.
-
Dependencies: Clearly define dependencies by layer. Reverse dependency is not allowed.
Development Guidelines
- Apply the layered design for implementation of all functions.
- All modules in the frameworks directory are platform-irrelevant. They cannot depend on modules in the adapter directory or other subsystems related to the JS engine.
- Platform-related code must be stored in the adapter directory of the related platform. If the code needs to be referenced in frameworks, proper interface abstraction is required.
- Non-OpenHarmony adapters cannot depend on modules of other OpenHarmony subsystems (except that the subsystem is designed for cross-platform purposes and is universal).
- frameworks/core cannot depend on the modules in frameworks/bridge.
- The new code cannot directly depend on the Skia interfaces. Use the drawing interfaces provided by graphic_2d.
- After the code in the OpenHarmony repository is modified, ensure that the build on each platform is successful and the functions are normal.