1 关键字

Ace相关库动态目标的单独编译方法

2 问题描述

代码版本:OpenHarmony-v3.1-Release

问题现象:客户在修改Ace相关库的源码js_view_functions.cpp文件()以后,尝试多种子部件单独编译命令形式均无法单独编译Ace相关库。

3 问题原因

3.1 正常机制

修改Ace相关库的源码以后,通过子部件编译命令,能成功单独编译Ace相关库。

3.2 异常机制

编译时提示找不到指定的编译目标

4 解决方案

foundation\ace\ace_engine\frameworks\bridge\declarative_frontend\jsview\js_view_functions.cpp属于declarative_js_engine模板中依赖的源文件。

declarative_js_engine模板是编译declarative_js_engine_相关前端引擎的。模板目标依赖于传入的目标参数,属于动态目标。

目标名称需要根据配置里的配置的要生成的引擎名,以及当前平台名拼接起来:

ark引擎:
./build.sh --product-name rk3568 -T declarative_js_engine_ark_ohos
​
qjS引擎:
./build.sh --product-name rk3568 -T declarative_js_engine_qjs_ohos

 

5 定位过程

1、declarative_js_engine模板动态目标定位分析:

1.1、通过搜索js_view_functions.cpp,找到依赖于js_view_functions.cpp源码的foundation\ace\ace_engine\frameworks\bridge\declarative_frontend\BUILD.gn。

通过这个BUILD.gn找到js_view_functions.cpp属于模板declarative_js_engine。

template("declarative_js_engine") {
  forward_variables_from(invoker, "*")
​
  ohos_source_set(target_name) {
    defines += invoker.defines
    ......
    deps = []
    configs = [ "$ace_root:ace_config" ]
​
    sources = [
      "engine/bindings_implementation.cpp",
      "engine/declarative_engine_loader.cpp",
      ......
      "jsview/js_view_functions.cpp",
      ......

1.2、模板的目标名来自于模板实例化后的target_name,查找到declarative_js_engine的调用位置如下,通过如下代码知道,declarative_js_engine传入的target_name为declarative_js_engine${engine.engine_name}$platform:

declarative_js_engine+引擎名+平台名

而引擎名和平台名均来自于ace_platforms里的枚举:

# dynamic generate js_engine targets
foreach(item, ace_platforms) {
  platform = item.name   #//平台名$platform来自于ace_platforms下的item的name
  engine_config = {
  }
  engine_config = item.config
  support_engines = []
  support_engines = engine_config.js_engines
  foreach(engine, support_engines) {
    declarative_js_engine(
        "declarative_js_engine_${engine.engine_name}_$platform") {
      platform = item.name
      engine_name = engine.engine_name
      engine_path = engine.engine_path
      defines = engine.engine_defines
​
      config = {
      }
      if (defined(item.config)) {
        config = item.config
      }
      if (defined(config.defines)) {
        defines += config.defines
      }
    }
  }

 

1.3、查找ace_platforms里的枚举信息来源:

查找到foundation\ace\ace_engine\ace_config.gni,通过ace_config.gni找到foundation\ace\ace_engine\adapter\ohos\build\platform.gni。

通过platform.gni确认$platform值为ohos。

而引擎配置来源于foundation\ace\ace_engine\adapter\ohos\build\config.gni。

而通过config.gni找到两个引擎配置:qjs_engine和ark_engine。他们对应的引擎名分别为qjs和ark

至此,编译这两个不同的引擎时,对应的动态目标分别为declarative_js_engine_qjs_ohos和declarative_js_engine_ark_ohos

确定了目标名之后,按照编译命令中指定单部件编译的命令格式(./build.sh --product-name xxx -T xxxxx)传入这些动态目标即可编译。

foundation\ace\ace_engine\ace_config.gni

......
ace_platforms = []
​
_ace_adapter_dir = rebase_path("$ace_root/adapter", root_build_dir)
_adapters = exec_script("build/search.py", [ _ace_adapter_dir ], "list lines")
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 ]
      }
    }
  }
}

 

foundation\ace\ace_engine\adapter\ohos\build\platform.gni

......
platforms = []
​
if (is_standard_system) {
  ohos_platform = {
    name = "ohos"
    config = {
      import("config.gni")
    }
  }
​
  platforms += [ ohos_platform ]
}

foundation\ace\ace_engine\adapter\ohos\build\config.gn

......
js_engines = []
qjs_engine = {
  engine_name = "qjs"       #//qjs_engine,引擎名为qjs
  engine_path = "quickjs"
  engine_defines = [ "USE_QUICKJS_ENGINE" ]
  have_debug = true
  declarative_default = true
}
js_engines += [ qjs_engine ]
ark_engine = {
  engine_name = "ark"      #//ark_engine,引擎名为ark
  engine_path = "jsi"
  engine_defines = [ "USE_ARK_ENGINE" ]
}
js_engines += [ ark_engine ]
......

 

 

6 知识分享

OpenHarmony编译目标指定的命令格式:

--build-target中指定的参数值:可以包括BUILD.gn中的可执行程序,动态库,group,action,部件名; 1、其中可执行程序,动态库,group,action这些尽量写全路径,BUILD.gn所在的路径:目标名 2、part_name作为目标时:要依据out/{device_name}/build_configs/{subsystem_name}/{part_name}:{part_name}这种方式有一个特别的指定 3、不支持指定subsystem_name

以Hi3516DV300编译的IPC举例: 1、直接编译ipc这个part_name,参照下列命令(注意要区分大小写,写成Hi3516DV300会编译不过,路径可以到out/hi3516dv300/build_configs/communication/ipc目录去取其BUILD.gn路径): ./build.sh --product-name Hi3516DV300 --build-target out/hi3516dv300/build_configs/communication/ipc:ipc

2、直接编译目标:ipc部件有3个目标(通过bundle.json得知的):ipc_single,ipc_core,libdbinder,指定全路径分别编译或拼接编译 ./build.sh --product-name Hi3516DV300 --build-target foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single ./build.sh --product-name Hi3516DV300 --build-target foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core ./build.sh --product-name Hi3516DV300 --build-target foundation/communication/ipc/interfaces/innerkits/libdbinder:libdbinder 拼接编译: ./build.sh --product-name Hi3516DV300 --build-target foundation/communication/ipc/interfaces/innerkits/libdbinder:libdbinder --build-target foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single --build-target foundation/communication/ipc/interfaces/innerkits/libdbinder:libdbinder 也支持使用-T简写来替代--build-target ./build.sh --product-name Hi3516DV300 -T foundation/communication/ipc/interfaces/innerkits/libdbinder:libdbinder -T foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single -T foundation/communication/ipc/interfaces/innerkits/libdbinder:libdbinder

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐