鴻蒙系統的編譯流程及分析v1.0(更新)


目錄

1.准備工作................................................................................................................ 2

2.全編譯+模塊編譯.................................................................................................. 3

3.編譯系統build目錄結構..................................................................................... 7

4.編譯結果out目錄結構........................................................................................ 8

5.構建系統Gn+Ninja............................................................................................. 11

6.編譯流程分析...................................................................................................... 14

  6.1設置環境hb set....................................................................................... 14

  6.2全編譯hb build........................................................................................ 14

  6.3增量編譯hb build [component]............................................................. 17

附錄一:hb build -T target的驗證....................................................................... 18

 

更新記錄

2021.04.17 v1.0 初始版本

 

說明:

因為新接觸鴻蒙系統的開發,我對鴻蒙的編譯系統基本上沒什么理解,都是憑着經驗和百度一邊學習一邊總結的,本文是我在學習網上關於鴻蒙系統的編譯相關資料后做的總結,經過了本人的實際操作驗證,部分知識點可能還有理解不到位的地方,未來會持續更新。

 

感謝:

官方文檔《輕量和小型系統編譯構建指導》

Link:https://device.harmonyos.com/cn/docs/develop/subsystems/oem_subsys_build_des-0000001060646620

《淺析鴻蒙中的Gn和Ninjia(一)》

Link: https://harmonyos.51cto.com/posts/2972

《GN語法和操作》

Link:https://blog.csdn.net/yujiawang/article/details/72627138

《HarmonyOS單模塊編譯與源碼導讀》【本文內簡稱為《導讀》】

Link:https://harmonyos.51cto.com/posts/3094

《HarmonyOS 2.0研究(1) -環境搭建及編譯過程分析》【強烈推薦】【本文內簡稱為《過程分析》】

Link:https://my.oschina.net/u/2502829/blog/4613535

《#2020征文-開發板#鴻蒙liteos-a如何啟動第一個用戶進程init_lite》【本文內簡稱為《如何啟動init_lite》】

Link:https://harmonyos.51cto.com/posts/1998#bkwz

 

 

 

1.准備工作
我的本地代碼是基於最新發布的OpenHarmony 1.1.0 LTS(2021-04-01)版本抓取的,代碼根目錄OHOS1_1_0LTS:

        $repo init -u https://gitee.com/openharmony/manifest.git -b refs/tags/OpenHarmony_release_v1.1.0 --no-repo-verify

        $repo sync

 

我還有Hi3861_Wifiiot開發板和開發環境,如下:

在Linux環境下的DecEco IDE下創建新工程“Test_Wifiiot”,在“HPM”標簽下找到“@ohos/wifi_iot”,點擊“Install to project”選擇“Test_Wifiiot”項目,開始下載並安裝組件到項目里。

 

2.全編譯+模塊編譯
2.1  OHOS1_1_0LTS的全代碼編譯

在代碼根目錄下執行:

OHOS1_1_0LTS$ hb set

[OHOS INFO] Input code path: .

OHOS Which product do you need?  

ipcamera_hispark_pegasus@hisilicon

-> ipcamera_hispark_taurus@hisilicon

ipcamera_hispark_aries@hisilicon

這一步完成后,會在代碼根目錄下生成“ohos_config.json”文件,然后就可以開始編譯了:

OHOS1_1_0LTS$ hb build

OHOS1_1_0LTS$ python build.py

OHOS1_1_0LTS$ python build.py -p ipcamera_hispark_taurus@hisilicon

效果都是一樣的。

 

第一次全編譯了2491個文件,以后再操作上面的命令就不是全編譯了,只編譯需要編譯的部分。

 

2.2  Test_Wifiiot項目的全編譯

新下載的項目代碼根目錄下並沒有“build.py”文件。

$ hb set

會生成“ohos_config.json”,但沒有完成配置,hb build 會失敗。

 

可以執行

$ln -s ./build/lite/build.py build.py

創建build.py的軟鏈接,再執行

$python build.py wifiiot

就可以正常編譯了。

 

Test_Wifiiot項目還可以用DevEco IDE進行一鍵編譯,操作步驟見官方的文檔:

https://device.harmonyos.com/cn/docs/ide/user-guides/service_introduction-0000001050166905

 

2.3  OHOS1_1_0LTS的組件/倉庫/Target編譯

 

一開始,關於模塊編譯,我在網上搜到了:

《HarmonyOS單模塊編譯與源碼導讀》(Link: https://harmonyos.51cto.com/posts/3094 )

這篇文章(下文簡稱《導讀》),仔細閱讀,並對比本地代碼OHOS1_1_0LTS查看了build\lite目錄下,並沒有上文所提到的compile.py文件和product目錄,這個可能是鴻蒙系統迭代更新版本給拿掉了。

 

查看OHOS1_1_0LTS\build\lite目錄下的README_zh.md,雖然看到增加了-T的說明:

-T [TARGET [TARGET ...]], --target [TARGET [TARGET ...]]

  Compile single target

但沒做進一步使用說明,因為對鴻蒙的編譯系統還沒多少了解,我還是不大清楚如何使用操作。

 

官方文檔“輕量和小型系統編譯構建指導”:

https://device.harmonyos.com/cn/docs/develop/subsystems/oem_subsys_build_des-0000001060646620

可能沒有更新,甚至沒有對“-T”參數的描述。

 

不過官方文檔中“組件描述位於build/lite/components下”這句話倒提醒了我,去里面看了一下,

原來這就是鴻蒙系統所有組件描述文件的存放位置,每個組件文件內又有多個【組件和target】的描述。

打開“applications.json”看一下,這里就有上面《導讀》提到的東西:

      "component": "camera_sample_app",

      "description": "Camera related samples.",

      "optional": "true",

      "dirs": [

        "applications/sample/camera/launcher",

        "applications/sample/camera/cameraApp",

        "applications/sample/camera/setting",

        "applications/sample/camera/gallery",

        "applications/sample/camera/media"

      ],

      "targets": [

        "//applications/sample/camera/launcher:launcher_hap",

        "//applications/sample/camera/cameraApp:cameraApp_hap",

        "//applications/sample/camera/setting:setting_hap",

        "//applications/sample/camera/gallery:gallery_hap",

        "//applications/sample/camera/media:media_sample"

      ],

趕緊操作一下:

OHOS1_1_0LTS$ hb build -T //applications/sample/camera/launcher:launcher_hap

編譯OK,不過時間還是有點長

 

 

官方文檔說“組件即為gn中的編譯單元,可以為靜態庫、動態庫或可執行文件。”

編譯構建流程圖上也是寫 hb build [component]

 

OHOS1_1_0LTS$ hb build camera_sample_app

編譯OK,但感覺與target編譯以及最上面hb build是一樣的效果~~

 

 

我還在OHOS1_1_0LTS\applications\sample\camera\README_zh.md 文檔中看到對媒體子系統組件的使用說明:

單倉的編譯構建,在根目錄下進行單倉的構建和編譯

# 開發板選擇

hb set  

# 單倉構建和編譯

hb build camera_lite

再查看一下build\lite\components\multimedia.json,原來單倉編譯就是組件編譯,而Target編譯,實際上看起來又與組件編譯差別不大,有些組件本身就是一個target,有些組件分多個target。

      "component": "camera_lite",

      "description": "Camera service.",

      "optional": "true",

      "dirs": [

        "foundation/multimedia/camera_lite",

        "foundation/multimedia/utils/lite/hals"

      ],

      "targets": [

        "//foundation/multimedia/camera_lite/frameworks:camera_lite"

      ],

 

小結:

鴻蒙系統所有組件描述文件的存放在build/lite/components/目錄下,每個組件文件內又有多個組件和target的描述。

組件/倉庫編譯指令:

$hb build component_name

Target編譯指令(可一次編譯多個target,用&&連接):

$hb build -T target_name

$hb build -T target1_name&&target2_name

 

3.編譯系統build目錄結構
首先必須要仔細研讀 build\lite\README_zh.md 文檔,文檔上沒有的地方,我這里補充一下我的理解,做成表格更容易管理。這個表格會在以后學習過程中根據新的理解做更新。

鴻蒙系統的編譯流程及分析v1.04.編譯結果out目錄結構

鴻蒙系統的編譯流程及分析v1.0鴻蒙系統的編譯流程及分析v1.0

打開“os-release”文件查看:

VERSION="OpenHarmony 1.0"

RELEASE_TIME="2021-04-18 07:38:53" 

分別是鴻蒙系統的版本號,和當次編譯(內核?系統?)的時間

 

5.構建系統Gn+Ninja
在學習鴻蒙之前,我對Gn/Ninja並不了解,只是知道有這么個東西,因為用不到所以也沒有去學習的動力。

這幾天因為想深入了解一下鴻蒙的編譯系統,就通過網絡資源簡單學習了一下,也只是知道了個大概,我看到的資料里覺得比較好的,有如下鏈接:

 

首先最重要的“gn help <command>”和官方文檔“The Ninja build system”,隨用隨查。

【下文中對gn定義的關鍵字不再解釋,請自行隨時 gn help。】

 

《淺析鴻蒙中的Gn和Ninjia(一)》

Link: https://harmonyos.51cto.com/posts/2972

《HarmonyOS 2.0研究(1) -環境搭建及編譯過程分析》【強烈推薦】【本文內簡稱為《過程分析》】

Link:https://my.oschina.net/u/2502829/blog/4613535

《#2020征文-開發板#鴻蒙liteos-a如何啟動第一個用戶進程init_lite》【本文內簡稱為《如何啟動init_lite》】

Link:https://harmonyos.51cto.com/posts/1998#bkwz

《GN語法和操作》

Link:https://blog.csdn.net/yujiawang/article/details/72627138

 

 

為了快速理解Gn+Ninja是如何工作的,我自己做了一個 GnHelloWorld工程來做測試和驗證,源代碼放在gitee上:

https://gitee.com/liangkzgitee/GnProjs.git

壓縮包也添加在本文附件里,請大家按readme.txt文檔操作,逐步進行跟蹤和分析。

 

readme.txt 文檔內容如下:

這是一個最簡單的Gn+Ninja構建系統的例子工程,通過這個簡單的工程和下面的操作,

學習Gn+Ninja構建系統是如何構建編譯我們的源代碼的。

原始工程目錄如下:

GnHelloWorld/                  #工程根目錄

├──build/                    #編譯構建主目錄

│     └──config/               #編譯相關的配置項

│             ├──toolchans/         #編譯工具鏈相關

│             │     └──BUILD.gn      #編譯選項、鏈接選項等等

│             └──BUILDCONFIG.gn    #指定默認編譯工具鏈

├──src/                      #源代碼目錄

│     ├──BUILD.gn              #(*)

│     └──hello.c                #(*)源代碼

├──.gn                       #Gn構建系統入口

├──BUILD.gn                  #

└──Readme.txt                #(*)本文

 

 

Step1:

在"GnHelloWorld"目錄下執行:"gn gen out"命令后,會生成一個"out"目錄,

GnHelloWorld/

├──......[略]

├──out/

│  ├──obj/

│  │      └──src/

│  │             └──hello.ninja    #編譯hello.c的ninja腳本

│  ├──args.gn              #構建參數

│  ├──build.ninja          

│  ├──build.ninja.d

│  └──toolchain.ninja

├──......[略]

 

 

Step2: [建議操作這步之前,先備份out目錄,如: "cp -r out out_bak"]

在"GnHelloWorld"目錄下執行: "ninja -C out",會在out目錄下生成

GnHelloWorld/

├──......[略]

├──out_bak/               #Step1 的 out 目錄的副本

│     ├──obj/

│     │     └──src/

│     │             └──hello.ninja

│     ├──args.gn

│     ├──build.ninja

│     ├──build.ninja.d

│     └──toolchain.ninja

├──out/                     #out目錄有更新,見#

│    ├──obj/

│    │     ├──src

│    │     │     ├──hello.ninja

│    │     │     └──hello.o        #編譯鏈工具根據規則生成的 .o

│    │     └──all.stamp          #

│    ├──.ninja_deps            #

│    ├──.ninja_log             #

│    ├──args.gn

│    ├──build.ninja

│    ├──build.ninja.d

│    ├──hello                 #編譯后生成的可執行文件

│    └──toolchain.ninja

├──......[略]

 

Step3:

在"GnHelloWorld"目錄下執行: 執行"./out/hello",輸出"Hello Gn World!"

 

Step1做了如下工作:

1.執行gn gen 時帶的參數被記錄下來,生成out/args.gn【本例不帶args參數】

2.找到 “.gn”文件並將其所在的目錄設為“souce root”,解析該文件以獲取buildconfig。

3.執行buildconfig所指向的文件BUILDCONFIG.gn,設置一個默認的編譯工具鏈,

  生成out/toolchain.ninja。

4.加載“souce root”目錄下的“BUILD.gn”文件,根據其內容加載它依賴的其它

  目錄下的BUILD.gn文件,生成out/build.ninja.d。

5.根據out/build.ninja.d中各個BUILD.gn的內容,遞歸解決各自的依賴關系,

  解決掉依賴關系之后,就在out/obj/對應目錄下,生成“.ninja”,

  如例子中的“out/obj/src/hello.ninja”。

6.解決掉所有的依賴關系后,在out/目錄下生成一個“build.ninja”。

 

Step2做了如下工作:

根據上面的.ninja文件所定義的規則和依賴關系,依次編譯出各自的中間文件,

最終生成可執行文件“out/hello”。

 

理解了上面的東西之后,你就可以開始進一步學習更復雜的東西了,可以參考Gn的官方文檔,

或者網絡上的其它資源,自己動手做驗證。

 

6.編譯流程分析
我們repo/sync完整個鴻蒙代碼后,要編譯系統,一般做以下三步:

1. 首次編譯,需要首先 hb set

2. 首次編譯,hb build 會啟動全編譯

3. 修改某個文件,比如 init_lite 的main 文件main函數加行log,再次編譯 hb build或者hb build init_lite。

 

這三步操作,鴻蒙的編譯系統都做了哪些具體工作?

帶着這個疑問,我希望能夠抽絲剝繭,一步一步來確認,可能中間會有暫不理解的,先跳過,未來再做進一步完善。

可惜目前我對python的了解也不多,無法對相關腳本做非常詳細的分析,對Gn構建系統的理解也還不夠深入,無法給出理想的分析結果,所以只能先把我現在知道的寫下來,以后學習過程中逐步補充完善。

 

6.1設置環境hb set
【查看/build/lite/README_zh.md】

設置OpenHarmony源碼目錄和要編譯的產品,在代碼根目錄生成“ohos_config.json”文件。

 

具體 hb set命令怎么調用/build/lite/hb/目錄下的相關腳本,再結合系統環境變量$PATH等相關必要信息來生成這個.json文件的,懂python的可以進去看一下。

 

打開“ohos_config.json”文件查看:

{

  "root_path": "/home/lkz/Work/OHOS1_1_0LTS",

  "board": "hispark_taurus",

  "kernel": "liteos_a",

  "product": "ipcamera_hispark_taurus",

  "product_path": "/home/lkz/Work/OHOS1_1_0LTS/vendor/hisilicon/hispark_taurus",

  "device_path": "/home/lkz/Work/OHOS1_1_0LTS/device/hisilicon/hispark_taurus/sdk_liteos"

}

這些將作為非常重要的參數交給下一步編譯使用。

 

6.2全編譯hb build
【查看/build/lite/README_zh.md】

編譯產品、開發板或者組件。解決方案編譯實現如下:

A. 讀取開發板配置:主要包括開發板使用的編譯工具鏈、編譯鏈接命令和選項等。

B.  調用gn: 調用gn gen命令,讀取產品配置(主要包括開發板、內核、選擇的組件等)生成解決方案out目錄和ninja文件。

C.  調用ninja:調用ninja -C out/company/product啟動編譯。

D.  系統鏡像打包:將組件編譯產物打包,制作文件系統鏡像。

說的很“框架”,下面我們一步一步來看一下。

 

A. 檢測/讀取/配置所有的必要參數
包括但不限於以下列出來的幾個文件:

  • ohos_config.json
  • Build\lite\ohos_var.gni   定義使用於所有組件的全局變量
  • device\hisilicon\hispark_pegasus\sdk_liteos\config.gni  這是編譯LiteOS_A內核所需要用到的配置
  • vendor\hisilicon\hispark_taurus\config.json  這是hisilicon提供的產品全量配置表:子系統、組件列表等等
  • 通過hb build傳進去的參數,比如 -n 表示編譯NDK,則會將ohos_build_ndk變量由默認的FALSE改為TRUE。

 

B. 調用gn gen命令生成out目錄和ninja文件
很復雜,也很簡單。

復雜是中間涉及到太多的Python和Gn語法,我暫時無法完整理解。

簡單是因為我做過了上面的GnHelloWorld工程來做測試和分析,知道了框架。

更詳細的分析過程,請看《過程分析》這篇文章。

 

下面是我對//build/lite/BUILD.gn這個文件中的 group("ohos") 的分解,最終得到"ohos"的完整的依賴關系:

鴻蒙系統的編譯流程及分析v1.0鴻蒙系統的編譯流程及分析v1.0

鴻蒙系統的編譯流程及分析v1.0鴻蒙系統的編譯流程及分析v1.0

C. 調用ninja啟動編譯
這里就開始根據上一步生成的 .ninja 文件里的規則調用編譯工具鏈來編譯各目錄下的源文件了,生成 .o/.a/.so/可執行文件 等等,其中.so文件會先在out\hispark_taurus\ipcamera_hispark_taurus\目錄下生成,等編譯完之后會轉移到out\hispark_taurus\ipcamera_hispark_taurus\libs\usr\目錄下,還生成了.ninja_log和.ninja_deps文件。

 

D. 打包制作系統鏡像
【暫未清晰理解,略】

 

6.3增量編譯hb build [component]
【暫未清晰理解,略】

 

附錄一:hb build -T target的驗證

【多圖,見附件文檔,此處略】

下載原文PDF及附件文檔

作者:liangkz

想了解更多內容,請訪問51CTO和華為合作共建的鴻蒙社區:https://harmonyos.51cto.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM