1. 程式人生 > 其它 >Open Harmony移植:build lite編譯構建過程

Open Harmony移植:build lite編譯構建過程

摘要:本文介紹了build lite 輕量級編譯構建系統編譯構建過程,呼叫依賴關係等等。

本文分享自華為雲社群《移植案例與原理 - build lite編譯構建過程》,作者: zhushy。

配置完畢產品解決方案、晶片開發板解決方案,就可以執行 hb build進行編譯。但是產品解決方案程式碼是如何被呼叫編譯的?

晶片開發板解決方案程式碼是如何被呼叫編譯的?核心程式碼如何被呼叫編譯的?解決了這些疑惑,會對build lite編譯構建過程有個更深入的理解。

1、產品解決方案程式碼是如何被呼叫編譯的

在檔案build\lite\BUILD.gn配置檔案中的構建目標//build/lite:product的程式碼片段如下,可以看出產品解決方案是被//build/lite:product呼叫的。其中⑴處的ohos_build_target,由hb build -T XX 構建引數指定,一般不指定時為空。

  group("product") {
    deps = []

    # build product, skip build single component scenario.
⑴  if (ohos_build_target == "") {
        deps += [ "${product_path}" ]
    }
    }

//build/lite:product 又進一步被什麼模組呼叫?在恆玄的程式碼配置檔案device\soc\bestechnic\bes2600\BUILD.gn中使用了,非恆玄的沒有呼叫//build/lite:product。所以,除了//build/lite:product,還有其他呼叫編譯產品解決方案程式碼的地方。

以vendor\goodix\gr5515_sk_iotlink_demo為例,來了解下什麼地方會呼叫編譯產品解決方案程式碼。產品解決方案根目錄下有檔案vendor\goodix\gr5515_sk_iotlink_demo\ohos.build,片段如下。可以看到,有子系統subsystem和部件資訊parts。

{
  "parts": {
    "product_gr5515_sk_iotlink_demo": {
      "module_list": [
        "//vendor/goodix/gr5515_sk_iotlink_demo:gr5515_sk_iotlink_demo
", "//vendor/goodix/gr5515_sk_iotlink_demo:image" ] } }, "subsystem": "product_gr5515_sk_iotlink_demo" }

在編譯構建時,會基於ohos.build檔案,解析子系統和部件資訊,生成到out\gr5515_sk\gr5515_sk_iotlink_demo\build_configs\parts_info\subsystem_parts.json檔案中,片段如下。這些解析出來的子系統和部件資訊,編譯構建構建hb會組織進行編譯構建。

  "product_gr5515_sk_iotlink_demo": [
    "product_gr5515_sk_iotlink_demo"
  ],

2、晶片開發板解決方案程式碼是如何被呼叫編譯的

在檔案kernel\liteos_m\BUILD.gn中定義的名為modules構建目標,這個modules構建目標依賴晶片開發板解決方案的程式碼。。⑴處判斷晶片和開發板是否是否進行了資料夾解耦,如果開發板路徑包含“/board/”,說明soc和board進行了解耦。根據是否解耦,依賴的晶片開發板的構建配置檔案路徑是不同的,見⑵。

    # board and soc decoupling feature, device_path should contains board
⑴  BOARD_SOC_FEATURE = device_path != string_replace(device_path, "/board/", "")
    ......
    group("modules") {
    deps = [
        "arch",
        "components",
        "kal",
        "kernel",
        "testsuites",
        "utils",
        HDFTOPDIR,
    ]

⑵  if (BOARD_SOC_FEATURE) {
        deps += [ "//device/board/$device_company" ]
        deps += [ "//device/soc/$LOSCFG_SOC_COMPANY" ]
    } else {
        if (HAVE_DEVICE_SDK) {
        deps += [ device_path ]
        }
    }
    }

名為modules構建目標又被libkernel構建目標、進一步被名為kernel的構建目標呼叫,如下所示。核心的kernel構建目標如何被呼叫,下一小節分析。

static_library("libkernel") {
  deps = [ ":modules" ]
  complete_static_lib = false
}

group("kernel") {
  deps = [ ":libkernel" ]
}

3、核心程式碼如何被呼叫編譯的

上文分析了產品解決方案、晶片開發板解決方案如何被呼叫的。本小節,追蹤下核心程式碼是如何被呼叫編譯的。

在生成的檔案out\v200zr\display_demo\build_configs\kernel\liteos_m\BUILD.gn中,會呼叫名為kernel、build_kernel_image的構建目錄。怎麼生成的這個檔案,需要研究下hb的程式碼,深入瞭解下後臺的機制,希望後續有時間可以繼續深入一些。

  import("//build/ohos/ohos_kits.gni")
    import("//build/ohos/ohos_part.gni")
    import("//build/ohos/ohos_test.gni")

    ohos_part("liteos_m") {
    subsystem_name = "kernel"
    module_list = [
        "//kernel/liteos_m:kernel",
        "//kernel/liteos_m:build_kernel_image",
    ]
    origin_name = "liteos_m"
    variant = "phone"
    }

構建目標build_kernel_image可以生成bin檔案,該目標依賴copy_liteos,copy_liteos依賴liteos構建目標,該目標會進一步呼叫//build/lite:ohos。//build/lite:ohos檔案會依次呼叫各個子系統和部件的構建目標。

  executable("liteos") {
    configs += [
        ":public",
        ":los_config",
    ]

    ldflags = [
        "-static",
        "-Wl,--gc-sections",
        "-Wl,-Map=$liteos_name.map",
    ]

    output_dir = target_out_dir

    if (liteos_kernel_only) {
        deps = [ ":kernel" ]
    } else {
        deps = [ "//build/lite:ohos" ]
    }
    }

    copy("copy_liteos") {
    deps = [ ":liteos" ]
    sources = [ "$target_out_dir/unstripped/bin/liteos" ]
    outputs = [ "$root_out_dir/$liteos_name" ]
    }

    build_ext_component("build_kernel_image") {
    deps = [ ":copy_liteos" ]
    exec_path = rebase_path(root_out_dir)

    objcopy = "${compile_prefix}objcopy$toolchain_cmd_suffix"
    objdump = "${compile_prefix}objdump$toolchain_cmd_suffix"

    command = "$objcopy -O binary $liteos_name $liteos_name.bin"
    command +=
        " && sh -c '$objdump -t $liteos_name | sort >$liteos_name.sym.sorted'"
    command += " && sh -c '$objdump -d $liteos_name >$liteos_name.asm'"
    }

4、名為public的config

在檔案kernel\liteos_m\BUILD.gn中,名為public的config定義如下。⑴處判斷晶片和開發板是否是否進行了資料夾解耦,如果開發板路徑包含“/board/”,說明soc和board進行了解耦。根據是否解耦,依賴的public的配置集的位置是不同的,見⑵。在晶片、開發板程式碼目錄中的BUILD.gn檔案中並沒有發現config(“public”),這個比較奇怪。

   # board and soc decoupling feature, device_path should contains board
⑴  BOARD_SOC_FEATURE = device_path != string_replace(device_path, "/board/", "")

    config("public") {
    configs = [
        "arch:public",
        "kernel:public",
        "kal:public",
        "components:public",
        "utils:public",
    ]

⑵  if (BOARD_SOC_FEATURE) {
        configs += [ "//device/board/$device_company:public" ]
        configs += [ "//device/soc/$LOSCFG_SOC_COMPANY:public" ]
    } else {
        if (HAVE_DEVICE_SDK) {
        configs += [ "$device_path:public" ]
        }
    }
    }

參考站點

 

 

 

點選關注,第一時間瞭解華為雲新鮮技術~