代碼工程及構建介紹
背景
ArkUI作為OpenHarmony的默認開發框架,在本項目(ArkUI-X)中需要做到一套代碼同時支持多平臺構建,所以會采取共倉開發的方式,部分倉直接指向OpenHarmony相關開源倉。
代碼結構及倉庫結構
代碼工程的目錄結構如下:
├── arkcompiler // 方舟編譯器
├── base // 基礎能力
├── build // 項目構建和配置腳本
├── build_plugins // 跨平臺構建插件
├── commonlibrary // 公共基礎庫
├── community // 社區相關
├── developtools // 開發者工具
├── docs // 配套文檔
├── foundation
│ ├── appframework // 應用框架兼容適配層
│ ├── arkui // ArkUI引擎
│ ├── communication // 通信能力
│ ├── distributeddatamgr // 分布式數據管理
│ ├── filemanagement // 文件管理
│ ├── graphic // 圖形引擎
│ └── multimedia // 多媒體
├── interface // 接口聲明
├── plugins // 插件管理與實現
├── prebuilts // 預編譯目錄
├── productdefine // 產品形態配置
├── samples // 示例代碼
├── test // 測試框架與用例
└── third_party // 三方庫
具體的代碼結構及指向,見下表:
目錄路徑 | 描述 | 代碼倉位置 |
---|---|---|
build | 項目構建和配置腳本 | [OpenHarmony/build] |
build_plugins | 跨平臺構建插件 | [ArkUI-X/build_plugins] |
samples | 應用程序樣例 | [ArkUI-X/samples] |
community | 社區運作管理 | [ArkUI-X/community] |
docs | 說明文檔 | [ArkUI-X/docs] |
interface/sdk | ArkUI-X SDK配置 | [ArkUI-X/interface_sdk] |
plugins | API插件管理,OpenHarmony API插件實現 | [ArkUI-X/plugins] |
test/xts | ArkUI-X跨平臺應用測試套件 | [ArkUI-X/xts] |
test/testfwk/arkxtest | ArkUI-X測試框架 | [ArkUI-X/arkxtest] |
developtools/ace_tools | 跨平臺命令行工具 | [ArkUI-X/cli] |
foundation/appframework | 應用框架兼容適配層 | [ArkUI-X/app_framework] |
foundation/arkui/ace_engine/adapter/android | Android平臺適配代碼 | [ArkUI-X/arkui_for_android] |
foundation/arkui/ace_engine/adapter/ios | iOS平臺適配代碼 | [ArkUI-X/arkui_for_ios] |
foundation/arkui/ace_engine | ArkUI 引擎核心代碼 | [OpenHarmony/arkui_ace_engine] |
foundation/arkui/napi | Native API擴展機制 | [OpenHarmony/arkui_napi] |
foundation/communication/netmanager_base | 網絡管理模塊 | [OpenHarmony/communication_netmanager_base] |
foundation/communication/netstack | 網絡協議棧 | [OpenHarmony/communication_netstack] |
foundation/graphic/graphic_2d | 2D圖形基礎庫 | [OpenHarmony/graphic_graphic_2d] |
foundation/filemanagement/file_api | 提供目錄和文件的訪問操作接口 | [OpenHarmony/filemanagement_file_api] |
foundation/multimedia/image_framework | 圖片編解碼功能實現 | [OpenHarmony/multimedia_image_framework] |
developtools/ace_ets2bundle | 基于ArkTS的聲明式開發范式編譯轉換工具和跨平臺應用構建工具 | [OpenHarmony/ace_ets2bundle] |
developtools/ace_js2bundle | 兼容JS的類Web開發范式編譯轉換工具和跨平臺應用構建工具 | [OpenHarmony/ace_js2bundle] |
arkcompiler/ets_frontend | 方舟前端工具 | [OpenHarmony/arkcompiler_ets_frontend] |
arkcompiler/ets_runtime | 方舟ArkTS運行時 | [OpenHarmony/arkcompiler_ets_runtime] |
arkcompiler/runtime_core | 方舟編譯器運行時 | [OpenHarmony/arkcompiler_runtime_core] |
arkcompiler/toolchain | 調試調優工具 | [OpenHarmony/arkcompiler_toolchain] |
prebuilts | 預編譯目錄,python,nodejs,clang和cmake等 | 通過腳本預下載 |
third_party | 開源第三方組件(統一復用OpenHarmony代碼倉) | 引用開源三方庫集合 |
commonlibrary/c_utils | 通用的C++功能函數和類 | [OpenHarmony/commonlibrary_c_utils] |
commonlibrary/ets_utils | 用于存放基礎類庫JSAPI,比如url、uri等 | [OpenHarmony/commonlibrary_ets_utils] |
base/hiviewdfx/hilog | 系統日志功能 | [OpenHarmony/hiviewdfx_hilog] |
base/web/webview | WebView組件的Native引擎 | [OpenHarmony/web_webview] |
base/global/resource_management | 全球化資源管理 | [OpenHarmony/global_resource_management] |
分支同步策略
OpenHarmony相關代碼倉,指向OpenHarmony master分支的固定tag點,定期同步,默認按照OpenHarmony的Weekly分支頻率進行同步。
ArkUI引擎核心代碼倉目錄結構
ArkUI引擎核心代碼倉?ace_engine
?的目錄結構以及每個目錄的內容如下:
foundation/arkui/ace_engine
├── ace_config.gni // 全局配置文件
├── adapter // 平臺適配層
│ ├── android // Android平臺適配,獨立倉
│ │ ├── build
│ │ ├── capability
│ │ ├── entrance
│ │ ├── stage
│ │ └── osal
│ ├── ios // iOS平臺適配,獨立倉
│ │ ├── build
│ │ ├── capability
│ │ ├── entrance
│ │ ├── stage
│ │ └── osal
│ ├── ohos // OpenHarmony平臺適配
│ └── preview // 預覽器平臺適配
├── build // 編譯配置
│ ├── ace_gen_obj.gni
│ ├── ace_lib.gni
│ ├── BUILD.gn
│ ├── search.py
│ └── tools
├── BUILD.gn // 全局編譯配置
├── frameworks // 引擎框架層
│ ├── base // base庫
│ ├── bridge // 前端橋接
│ └── core // 引擎核心實現
├── interfaces // 通用對外接口
│ └── napi
│ └── kits
├── LICENSE
├── OAT.xml
├── README.md
├── README_zh.md
└── test // 測試相關
編譯構建流程
為了支持一套代碼在OpenHarmony和其它平臺同時構建,需要根據代碼結構動態對編譯配置進行調整,因為對外依賴可能不同,并且不同環境下可能依賴的外部源碼都有差異,所以必須對編譯目標(targets)都進行動態的定義,否則無法保持一致。
- 編譯入口:??OpenHarmony的編譯入口為bundle.json,這里定義了子系統的部件以及對外的接口,放在對應子系統根目錄下,ArkUI的其它平臺構建暫不需要,使用固定模塊名“ace_packages”作為入口。
-
全局配置:??根目錄下的BUILD.gn以及ace_config.gni為全局的配置,其中BUILD.gn下定義了全局使用的“ace_config”、“ace_test_config”,其中ace_config.gni分別定義了以下配置:
- 全局的變量配置,如“enable_ace_debug”,通過開關進行編譯控制。
- 全局的路徑定義,如“ace_napi“,配置路徑的變量。
- 工具鏈相關的配置,如“windows_buildtool”。
- 在“ace_config”中使用的全局宏的定義,如“ace_common_defines”。
- 生成平臺相關的配置項“ace_platforms”,這一步是動態定義目標的關鍵,見如下代碼:
ace_platforms = []# 通過搜索adapter下的目錄,生成所有的adapter目錄名 _ace_adapter_dir = rebase_path("$ace_root/adapter", root_build_dir) _adapters = exec_script("build/search.py", [ _ace_adapter_dir ], "list lines")# 導入每個adapter下的platform.gni,生成platform的定義配置,加入到ace_platforms中 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 ]}} } }
-
平臺配置:??每個adapter下的build目錄存放平臺相關的配置
├── BUILD.gn // 入口目標定義,如"ace_packages" ├── config.gni // 平臺配置 ├── bundle.json // 部件配置,非OpenHarmony平臺暫不需要 └── platform.gni // 平臺定義
其中,單個config.gni的配置類似如下:
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 = falseif (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", ]
這個文件定義了該平臺的所有差異化配置,如宏、cflags、平臺特有的依賴,以及一些功能性的開關。在具體的模塊定義中,宏、cflags這一類編譯配置直接從config引入,其它差異需要定義為功能性的開關,如上述的“use_curl_download”,使模塊gn及特性的定義更清晰。
-
動態目標定義:??基于上述平臺的配置,就可以實現動態的定義目標,以base模塊為例:
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) {# 引入平臺config中的define和cflagsdefines += invoker.definescflags_cc = []cflags_cc += invoker.cflags_ccdeps = ["$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 heresources = ["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",]# 通過platform變量來進行區別配置if (platform != "windows") {# add secure c APIinclude_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",]}# 通過平臺的config決定是否依賴和編譯curlif (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" ]}} }# 根據ace_platforms動態定義目標:假設里面包含三個平臺"ohos"、"windows"、"mac",則會定義三個target, # 分別為:ace_base_ohos,ace_base_windows,ace_base_mac foreach(item, ace_platforms) {ace_base_source_set("ace_base_" + item.name) {# 從platform中導入變量platform = item.namedefines = []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}} }
- 模塊定義:??根據目錄結構,盡量分成一個個小模塊來定義,每個模塊定義明確,如果涉及平臺差異,使用上述方法定義,內部配置差異盡量使用特性來區分
- 依賴關系:??依賴關系盡量清楚,按層次依賴,不可反向依賴
- 開發前請熟悉鴻蒙開發指導文檔:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md點擊或者復制轉到。
開發原則
- 所有功能實現遵循分層設計
- frameworks目錄下的所有模塊都是平臺無關的,不能依賴adapter目錄下的模塊,不能依賴除JS引擎相關的其它子系統
- 平臺相關的代碼都必須放到adapter目錄對應的平臺下,如果需要在frameworks中引用相關,需要進行適當的接口抽象
- 非OpenHarmony的adapter中不能依賴OpenHarmony其它子系統的模塊(例外:該子系統有跨平臺計劃并且通用)
- frameworks/core不允許依賴frameworks/bridge下的模塊
- 新增代碼不可直接依賴skia接口,使用graphic_2d提供的drawing接口
- 修改OpenHarmony倉中的內容要保證各平臺都能編譯通過,功能正常
鴻蒙最值得程序員入行
為什么這么說?市場是決定人力需求的,數據說話最管用:
1、鴻蒙其全棧自研,頭部大廠商都陸續加入合作開發鴻蒙原生應用——人才需求上漲。
2、鴻蒙作為新系統、新技術,而現在市面上技術人才少——高薪招聘開啟。
3、鴻蒙1+8+N生態,不僅只有應用開發;還有車載、數碼、智能家居、家電等——就業范圍廣。
4、純血鴻蒙,目前沒有多少人熟悉。都處于0基礎同一起跑線——無行業內卷。
開發者最需要什么?崗位多、薪資高、不內卷、行業競爭低。而當下的鴻蒙恰恰符合要求。
那么這么好的鴻蒙崗位,應聘要求都很高吧?其實不然鴻蒙作為新出的獨立系統,其源頭上大家都處于同一水平線上,一開始的技術要求都不會很高,畢竟面試官也是剛起步學習。招聘要求示例:
從信息看出,幾乎應職要求是對標有開發經驗的人群。可以說鴻蒙對開發者非常友好,盡管上面沒提鴻蒙要求,但是面試都會篩選具有鴻蒙開發技能的人。我們程序員都知道學習開發技術,最先是從語言學起,鴻蒙語言有TS、ArkTS等語法,那么除了這些基礎知識之外,其核心技術點有那些呢?下面就用一張整理出的鴻蒙學習路線圖表示:
從上面的OpenHarmony技術梳理來看,鴻蒙的學習內容也是很多的。現在全網的鴻蒙學習文檔也是非常的少,下面推薦一些:完整內容可在頭像頁保存,或這qr23.cn/AKFP8k甲助力
內容包含:《鴻蒙NEXT星河版開發學習文檔》
- ArkTS
- 聲明式ArkUI
- 多媒體
- 通信問題
- 系統移植
- 系統裁剪
- FW層的原理
- 各種開發調試工具
- 智能設備開發
- 分布式開發等等。
這些就是對往后開發者的分享,希望大家多多點贊關注喔!