• 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" ]
            }
        }
        }

    参考站点

     

     

     

    点击关注,第一时间了解华为云新鲜技术~

  • 相关阅读:
    常数时间国密算法
    A Guide to the Go Garbage Collector
    并发控制 互斥
    词典遍历顺序
    max size of IPv4 & IPv6 packet 包大小
    BufferOverflow Attacks
    unsigned 是表示无符号数据类型,
    回溯 递归 的回退状态
    抖音平台多产物代码隔离技术的实践与探索
    依赖注入 开发效率
  • 原文地址:https://www.cnblogs.com/huaweiyun/p/16012119.html
Copyright © 2020-2023  润新知