移植speexdsp到OpenHarmony标准系统③

speexdsp移植后已提交至openhamrony sig仓库:https://gitee.com/openharmony-sig/contest/tree/master/2022_OpenHarmony_thirdparty/speexdsp


四、将三方库加入到OpenHarmony的编译体系

根据上一步分析结果,编写gn文件,将三方库加入到OpenHarmony的编译体系。

OpenHarmony编译构建子系统提供了一个基于Gn和ninja的编译构建框架。根据产品配置,编译生成对应的镜像包。其中编译构建流程为:

  • 使用Gn配置构建目标。
  • Gn运行后会生成ninja文件。
  • 通过运行ninja来执行编译任务。

OpenHarmony三方库编译环境搭建

本次移植时在openharmony3.2Beta1版本上运行的,所以需要准备openharmony3.2Beta1的源码。

先在Widows上安装虚拟机,在虚拟机上安装Ubuntu18.04或者20.04。笔者使用的为Ubuntu20.04。

1.将Ubuntu Shell环境修改为bash

  • 打开终端执行

    sudo dpkg-reconfigure dash

  • 将Shell由dash改为bash。

  • 选择<否>
  • 更改成功如下:

2.下载华为集成开发环境 DevEco Device Tool Linux版本,目前最新版本号为3.1.0.200

HUAWEI DevEco Device Tool(以下简称DevEco Device Tool)是OpenHarmony面向智能设备开发者提供的一站式集成开发环境,支持OpenHarmony的组件按需定制,支持代码编辑、编译、烧录和调试等功能,支持C/C++语言,以插件的形式部署在Visual Studio Code上。

  • 直接在Ubuntu上打开firefox输入下载地址下载
  • 安装DevEco Device

  • 执行命令安装DevEco Device

    sudo ./devicetool-linux-tool-3.1.0.200.sh

终端打印出这条信息说明安装成功

3.获取标准系统源码

执行命令sudo apt-get install git git-lfs安装git客户端和git-lfs

  • 配置git用户信息

    git config --global user.name "yourname"
    git config --global user.email "your-email-address"
    git config --global credential.helper store

git config --global credential.helper store执行这个命令会在本地生成一个文本,上边记录配置。然后再拉取代码就不用再输入账号信息了。

  • 使用repo+https下载发布Tag节点源码

创建源码存放目录

进入创建的源码存放目录,执行以下命令下载源码

sudo ln -sf /usr/bin/python3 /usr/bin/python
repo init -u https://gitee.com/openharmony/manifest -b refs/tags/OpenHarmony-v3.2-Beta1 --no-repo-verify
repo sync -c
repo forall -c 'git lfs pull'

如果要下载最新分支的代码则执行:

repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify

3.在源码目录下执行脚本安装编译器及二进制工具

下载的prebuilts二进制默认存放在与OpenHarmony同目录下的OpenHarmony_2.0_canary_prebuilts下。

bash build/prebuilts_download.sh

如果执行bash build/prebuilts_download.sh出现以下warning,在源码/prebuilts/python/linux-x86/3.9.2/bin/执行python -m pip install --user --upgrade pip==22.3.1(22.3.1是要升级的版本号)

4.安装依赖工具

sudo apt-get install binutils git git-lfs gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 bc gnutls-bin python3.8 python3-pip ruby

如果安装了如上的依赖工具不行,执行以下语句安装最新的依赖工具

unix_time=`date '+%s'`;for one_tools in `curl -s -k https://gitee.com/landwind/openharmony_oneclick_env_init/raw/master/apt_install.list`;do echo "apt-get install -y ${one_tools}">>/tmp/openharmony_deps_${unix_time}.sh; done;sudo apt-get update;sudo bash -x /tmp/openharmony_deps_${unix_time}.sh

依赖工具列表 https://gitee.com/landwind/openharmony_oneclick_env_init/raw/master/apt_install.list

5.将python 3.8设置为默认python版本。

  • 查看python 3.8的位置:

    which python3.8

将python和python3切换为python3.8

sudo update-alternatives --install /usr/bin/python python {python3.8 路径} 1    
sudo update-alternatives --install /usr/bin/python3 python3 {python3.8 路径} 1  

6.最后测试一下OpenHarmony三方库编译环境

在源码根目录下执行编译命令

./build.sh --product-name rk3568 --ccache --build-target=要编译的部件名 --target-cpu arm64
#其中:--product-name rk3568 指定产品名为rk3568 
#其中:--ccache              编译使用ccache
#其中:--target-cpu arm64    编译构建64位系统

在源码目录下执行编译zlib命令,生成libzlib.z.so

./build.sh --product-name rk3568 --ccache --build-target=zlib

编译生成了libzlib.z.so,编译环境没问题。

OpenHarmony环境重置

  • 安装依赖包: unix_time=date '+%s';for one_tools in curl -s -k https://gitee.com/landwind/openharmony_oneclick_env_init/raw/master/apt_install.list`;do echo "apt-get install -y {one_tools}">>/tmp/openharmony_deps_{unix_time}.sh; done;sudo apt-get update;sudo bash -x /tmp/openharmony_deps_${unix_time}.sh`
  • 删除out: rm -rf out
  • 重置工作区,删除所有修改(记得备份你改的代码 ): repo forall -c "pwd;git reset --hard; git clean -fd"
  • 更新最新代码: repo sync -c -j8; repo forall -c "pwd;git lfs install;git lfs pull"
  • 执行prebuilts下载脚本: bash build/prebuilts_download.sh

配置speexdsp源码

下载完openharmony3.2Beta1源码后,将speexdsp的源码拷贝到openhamony的third_party目录下。

在OpenHarmony/sources/third_party/speexdsp和OpenHarmony/sources/third_party/speexdsp/libspeexdsp下分别编写一份BUILD.gn文件,完成speexdsp的gn及测试用例的gn化。测试用例指的是测试speexdsp功能的程序。

speexdsp编译gn化,新增工程构建脚本。

OpenHarmony/sources/third_party/speexdsp下添加BUILD.gn脚本文件。

OpenHarmony/sources/third_party/speexdsp/BUILD.gn内容如下:

import("//build/ohos.gni")  

config("speexdsp_nowarn_config"){
    cflags = [
         "-Wno-implicit-function-declaration",
         "-Wno-pointer-sign",
         "-Wno-unused-variable",
    ]
}

config("speexdsp_cflag_config"){
    cflags = [
         "-g",
         "-O2",
         "-fvisibility=hidden",
         "-DHAVE_CONFIG_H",

    ]
    ldflags = [
         "-lm"
    ]
}

ohos_shared_library("speexdsp_share") {
    sources = [
         "libspeexdsp/preprocess.c",
         "libspeexdsp/jitter.c",
         "libspeexdsp/mdf.c",
         "libspeexdsp/fftwrap.c",
         "libspeexdsp/filterbank.c",
         "libspeexdsp/resample.c",
         "libspeexdsp/buffer.c",
         "libspeexdsp/scal.c",
         "libspeexdsp/smallft.c",
         ]

    defines = [
        "NL_DEBUG",
        "speexdsp_EXPORTS",
    ]

    configs = [ 
         ":speexdsp_cflag_config", 
         ":speexdsp_nowarn_config"
    ] 
    include_dirs = [
         ".",
         "libspeexdsp",
         "include"
    ]
    part_name = "speexdsp"
}
代码解析

第一行:

import("//build/ohos.gni") 

import函数将ohos.gni文件导入到当前作用域。导入的文件是独立执行的,生成的作用域被复制到当前文件中。一个.gni文件会定义构建参数和模板。build目录下ohos.gni文件内容如下

import("//build/config/sanitizers/sanitizers.gni")
import("//build/ohos/ndk/ndk.gni")
import("//build/ohos/notice/notice.gni")
import("//build/ohos/sa_profile/sa_profile.gni")
import("//build/ohos_var.gni")
import("//build/toolchain/toolchain.gni")

# import cxx base templates
import("//build/templates/cxx/cxx.gni")
if (support_jsapi) {
  import("//build/ohos/ace/ace.gni")
  import("//build/ohos/app/app.gni")
}

import("//build/templates/common/ohos_templates.gni")

# import prebuilt templates
import("//build/templates/cxx/prebuilt.gni")

第三行到第九行:

config("speexdsp_nowarn_config"){
    cflags = [
         "-Wno-implicit-function-declaration",
         "-Wno-pointer-sign",
         "-Wno-unused-variable",
    ]
}
  • configs定义了该模块编译配置的环境变量speexdsp_nowarn_config,第24行ohos_shared_library定义了最终生成的模块名,这里代表此模块为最终生成libspeexdsp.z.so。所以在第五行到第七行中config中添加了编译libspeexdsp.z.so需要添加的编译器标志
    • 但是"-Wno-implicit-function-declaration"、"-Wno-pointer-sign""、-Wno-unused-variable"并非是分析speexdsp原生库得来的cflag编译器标志。
    • 而是后来在ohos上编译验证过程中,根据编译报错信息添加的。如果不添加它们,执行./build.sh --product-name rk3568 --ccache --build-target=speexdsp命令后,则无法编译生成openharmony上的运行的libspeexdsp.z.so库,会出现编译警告信息-W-implicit-function-declaration、-W-pointer-sign、-W-unused-variable。解决办法就是在gn化时添加cflag标志"-Wno-implicit-function-declaration"、"-Wno-pointer-sign""、-Wno-unused-variable"。
  • clang编译器警告消除:
    1.出现警告的就是直接在-W后面加no,比如-Wimplicit-function-declaration改为 -Wno-implicit-function-declaration
    2.还有另外的一种方法:-Wimplicit-function-declaration=no

第十一到第二十二行:

config("speexdsp_cflag_config"){
    cflags = [
         "-g",
         "-O2",
         "-fvisibility=hidden",
         "-DHAVE_CONFIG_H",

    ]
    ldflags = [
         "-lm"
    ]
}
  • configs定义了该模块编译配置的环境变量speexdsp_cflag_config,在第十三行到第十六行添加了编译需要添加的编译器标志 "-g","-O2","-fvisibility=hidden", "-DHAVE_CONFIG_H"。
    • "-g","-O2","-fvisibility=hidden"通过分析原生库config.log和makefile文件,具体请查看第二期内容。
    • "-DHAVE_CONFIG_H"通过分析执行build命令后编译ohos上speexdsp的so库报错信息得来
  • 添加"-DHAVE_CONFIG_H"后仍然有报错信息,解决办法是把linux下编译speexdsp原生库./configure后生成的config.h放置在thrid_party/speexdsp下。

第二十四行到第五十二行:

ohos_shared_library("speexdsp_share") {
    sources = [
         "libspeexdsp/preprocess.c",
         "libspeexdsp/jitter.c",
         "libspeexdsp/mdf.c",
         "libspeexdsp/fftwrap.c",
         "libspeexdsp/filterbank.c",
         "libspeexdsp/resample.c",
         "libspeexdsp/buffer.c",
         "libspeexdsp/scal.c",
         "libspeexdsp/smallft.c",
         ]

    defines = [
        "NL_DEBUG",
        "speexdsp_EXPORTS",
    ]

    configs = [ 
         ":speexdsp_cflag_config", 
         ":speexdsp_nowarn_config"
    ] 
    include_dirs = [
         ".",
         "libspeexdsp",
         "include"
    ]
    part_name = "speexdsp"
}

如果是生成静态库ohos_static_library(" ") { }

  • 第二十五行到第三十五行sources模块包含了需要编译的源码文件

  • 第四十六行到五十行include_dirs模块包含了编译依赖的头文件路径

  • 第五十一行part_name 该模块编译依赖的编译子系统组件名。该配置项是为了模块最终生成的so文件能在系统编译完后自动拷贝到系统目录中。如果没有配置该项,系统编译完后是不会自动将生成的so文件拷贝到系统目录。

测试用例gn化,新增工程构建脚本

OpenHarmony/sources/third_party/speexdsp/libspeexdsp下添加BUILD.gn脚本文件。

import("//build/ohos.gni")

config("test_nowarn_config"){
    cflags = [
         "-Wno-sign-compare",
         "-Wno-pointer-sign"
    ]
}

config("speexdsp_cflag_config") {
    ldflags = [ "-lm" ]
    cflags_cc = [
         "-g",
         "-O2",
         "-fvisibility=hidden",
    ]
}

config("speexdsp_config") {
    include_dirs = [
         "//third_party/speexdsp/include"
     ]
}

ohos_executable("testdenoise"){
    public_configs = [ 
          ":speexdsp_config",
          ":test_nowarn_config"
    ]
    sources = [
         "testdenoise.c"
    ]
    configs = [
         ":speexdsp_cflag_config",

    ]

    deps = [
         "//third_party/speexdsp:speexdsp_share"
    ]

    part_name = "speexdsp"
}

ohos_executable("testecho"){
    public_configs = [ 
          ":speexdsp_config",
          ":test_nowarn_config"
    ]
    sources = [
         "testecho.c"
    ]

    configs = [
         ":speexdsp_cflag_config"
    ]

    deps = [
         "//third_party/speexdsp:speexdsp_share"
    ]

    part_name = "speexdsp"
}

ohos_executable("testjitter"){
    public_configs = [ 
          ":speexdsp_config",
          ":test_nowarn_config"
    ]
    sources = [
         "testjitter.c"
    ]

    configs = [
         ":speexdsp_cflag_config"
    ]

    deps = [
         "//third_party/speexdsp:speexdsp_share"
    ]

    part_name = "speexdsp"
}

ohos_executable("testresample"){
    public_configs = [ 
          ":speexdsp_config",
          ":test_nowarn_config"
    ]
    sources = [
         "testresample.c"
    ]

    configs = [
         ":speexdsp_cflag_config"
    ]

    deps = [
         "//third_party/speexdsp:speexdsp_share"
    ]

    part_name = "speexdsp"
}

ohos_executable("testresample2"){
     public_configs = [ 
          ":speexdsp_config",
          ":test_nowarn_config"
    ]
    sources = [
         "testresample2.c"
    ]

    configs = [
         ":speexdsp_cflag_config"
    ]

    deps = [
         "//third_party/speexdsp:speexdsp_share"
    ]
    part_name = "speexdsp"

}
代码解析

测试用例gn化代码解析的内容与speexdsp编译gn化内容相似,这里不做重复解释,只补充以下几点。

  • 测试用例是在ohos上测试libspeexdsp.z.so功能用的。
  • 第28、48、68、88、108行:gn中的目标类型executable表示生成可执行文件testdenoise、testecho、testjitter、testresample、testresample2。
  • 第41、61、81、101、121行:deps表示测试用例模块编译依赖其他模块,这里指的是测试用例的编译依赖。libspeexdsp.z.so库。
  • 第45、65、85、105、125行:part_name表示测试用例模块编译依赖的编译子系统组件名。该配置项是为了模块最终生成的so文件能在系统编译完后自动拷贝到系统目录中。如果没有配置该项,系统编译完后是不会自动将生成的so文件拷贝到系统目录。

OpenHarmony/sources/third_party/speexdsp目录下添加ohos.build。

  • 定义子系统并加入到编译框架
    在系统源码根目录下创建一个目录作为子系统目录,子系统目录可创建在OpenHarmony源码目录任意位置。
    • 本项目以third_party/speexdsp作为为子系统目录,子系统名字即为speexdsp。

子系统speexdsp目录下创建ohos.build文件,build构建时会先读取该文件。

  "subsystem": "speexdsp",
  "parts": {
    "speexdsp": {
      "module_list": [
        "//third_party/speexdsp/libspeexdsp:testdenoise",
        "//third_party/speexdsp/libspeexdsp:testecho",
        "//third_party/speexdsp/libspeexdsp:testjitter",
        "//third_party/speexdsp/libspeexdsp:testresample",
        "//third_party/speexdsp/libspeexdsp:testresample2"
      ],
      "inner_kits": [
              ],
      "system_kits": [
      ],
      "test_list": [
      ]
    }
  }
}
  • build文件夹下的subsystem_config.json文件,主要包含子系统名称与路径信息,在preloader阶段被加载,根据子系统名称和路径信息查找该路径下的ohos.build文件。
  • 其中需要包含module_list、inner_kits、system_kits、test_list四个部分的声明:
    • module_list:部件包含的模块列表
    • inner_kits:部件提供其它部件的接口
    • system_kits:部件提供给生成应用的接口
    • test_list:部件对应模块的测试用例

修改build/subsystem_config.json,新增子系统定义。

在源码/build/subsystem_config.json中增加子系统选项,把子系统speexdsp配置到build/subsystem_config.json。

 "speexdsp": {
    "path": "third_party/speexdsp",
    "name": "speexdsp"
  },

注意:要求符合json语法规范,要在}前加,(如下图所示)

修改vendor/hihope/rk3568/config.json文件将speexdsp添加至rk3568开发板,在vendor目录下新增产品的定义。

将子系统及其组件加入产品定义中,以rk3568为例,产品定义文件在vendor/hihope/rk3568/config.json,需要将以下内容添加到config.json中:

{
      "subsystem": "speexdsp",
      "components": [
        {
          "component": "speexdsp",
          "features": []
        }
      ]
    },

下期分享内容:在OpenHarmony的编译体系下编译speexdsp的so和测试用的可执行文件,以及编译报错的解决办法

知识点附送

本文中知识点附送的内容并不和移植speexdsp到openharmony标准系统直接相关,仅作为拓展阅读的知识点,因此读者可以不作过细的了解。

gn

  • generate ninja工具,在out目录下生成ninja编译文件*.ninja,gn的可执行文件位置在prebuilts/build-tools/linux-x86目录里

  • GN基础语法介绍:https://gitee.com/personal-summary/gn

    jiajiahao@ubuntu:~/Desktop/OpenHarmony/sources/prebuilts/build-tools/linux-x86/bin$ ./gn --help

    Commands (type "gn help <command>" for more help):
    analyze: Analyze which targets are affected by a list of files.
    args: Display or configure arguments declared by the build.
    check: Check header dependencies.
    clean: Cleans the output directory.
    desc: Show lots of insightful information about a target or config.
    format: Format .gn files.
    gen: Generate ninja files.
    help: Does what you think.
    ls: List matching targets.
    meta: List target metadata collection results.
    path: Find paths between two targets.
    refs: Find stuff referencing a target or file.

    Target declarations (type "gn help <function>" for more help):
    action: Declare a target that runs a script a single time.
    action_foreach: Declare a target that runs a script over a set of files.
    bundle_data: [iOS/macOS] Declare a target without output.
    copy: Declare a target that copies files.
    create_bundle: [iOS/macOS] Build an iOS or macOS bundle.
    executable: Declare an executable target.
    generated_file: Declare a generated_file target.
    group: Declare a named group of targets.
    loadable_module: Declare a loadable module target.
    rust_library: Declare a Rust library target.
    rust_proc_macro: Declare a Rust procedural macro target.
    shared_library: Declare a shared library target.
    source_set: Declare a source set target.
    static_library: Declare a static library target.
    target: Declare an target with the given programmatic type.

    Buildfile functions (type "gn help <function>" for more help):
    assert: Assert an expression is true at generation time.
    config: Defines a configuration object.
    declare_args: Declare build arguments.
    defined: Returns whether an identifier is defined.
    exec_script: Synchronously run a script and return the output.
    foreach: Iterate over a list.
    forward_variables_from: Copies variables from a different scope.
    get_label_info: Get an attribute from a target's label.
    get_path_info: Extract parts of a file or directory name.
    get_target_outputs: [file list] Get the list of outputs from a target.
    getenv: Get an environment variable.
    import: Import a file into the current scope.
    not_needed: Mark variables from scope as not needed.
    pool: Defines a pool object.
    print: Prints to the console.
    process_file_template: Do template expansion over a list of files.
    read_file: Read a file into a variable.
    rebase_path: Rebase a file or directory to another location.
    set_default_toolchain: Sets the default toolchain name.
    set_defaults: Set default values for a target type.
    set_sources_assignment_filter: Set a pattern to filter source files.
    split_list: Splits a list into N different sub-lists.
    string_join: Concatenates a list of strings with a separator.
    string_replace: Replaces substring in the given string.
    string_split: Split string into a list of strings.
    template: Define a template rule.
    tool: Specify arguments to a toolchain tool.
    toolchain: Defines a toolchain.
    write_file: Write a file to disk.

    Built-in predefined variables (type "gn help <variable>" for more help):
    current_cpu: [string] The processor architecture of the current toolchain.
    current_os: [string] The operating system of the current toolchain.
    current_toolchain: [string] Label of the current toolchain.
    default_toolchain: [string] Label of the default toolchain.
    gn_version: [number] The version of gn.
    host_cpu: [string] The processor architecture that GN is running on.
    host_os: [string] The operating system that GN is running on.
    invoker: [string] The invoking scope inside a template.
    python_path: [string] Absolute path of Python.
    root_build_dir: [string] Directory where build commands are run.
    root_gen_dir: [string] Directory for the toolchain's generated files.
    root_out_dir: [string] Root directory for toolchain output files.
    target_cpu: [string] The desired cpu architecture for the build.
    target_gen_dir: [string] Directory for a target's generated files.
    target_name: [string] The name of the current target.
    target_os: [string] The desired operating system for the build.
    target_out_dir: [string] Directory for target output files.

    Variables you set in targets (type "gn help <variable>" for more help):
    aliased_deps: [scope] Set of crate-dependency pairs.
    all_dependent_configs: [label list] Configs to be forced on dependents.
    allow_circular_includes_from: [label list] Permit includes from deps.
    arflags: [string list] Arguments passed to static_library archiver.
    args: [string list] Arguments passed to an action.
    asmflags: [string list] Flags passed to the assembler.
    assert_no_deps: [label pattern list] Ensure no deps on these targets.
    bundle_contents_dir: Expansion of {{bundle_contents_dir}} in create_bundle.
    bundle_deps_filter: [label list] A list of labels that are filtered out.
    bundle_executable_dir: Expansion of {{bundle_executable_dir}} in create_bundle
    bundle_resources_dir: Expansion of {{bundle_resources_dir}} in create_bundle.
    bundle_root_dir: Expansion of {{bundle_root_dir}} in create_bundle.
    cflags: [string list] Flags passed to all C compiler variants.
    cflags_c: [string list] Flags passed to the C compiler.
    cflags_cc: [string list] Flags passed to the C++ compiler.
    cflags_objc: [string list] Flags passed to the Objective C compiler.
    cflags_objcc: [string list] Flags passed to the Objective C++ compiler.
    check_includes: [boolean] Controls whether a target's files are checked.
    code_signing_args: [string list] Arguments passed to code signing script.
    code_signing_outputs: [file list] Output files for code signing step.
    code_signing_script: [file name] Script for code signing.
    code_signing_sources: [file list] Sources for code signing step.
    complete_static_lib: [boolean] Links all deps into a static library.
    configs: [label list] Configs applying to this target or config.
    contents: Contents to write to file.
    crate_name: [string] The name for the compiled crate.
    crate_root: [string] The root source file for a binary or library.
    crate_type: [string] The type of linkage to use on a shared_library.
    data: [file list] Runtime data file dependencies.
    data_deps: [label list] Non-linked dependencies.
    data_keys: [string list] Keys from which to collect metadata.
    defines: [string list] C preprocessor defines.
    depfile: [string] File name for input dependencies for actions.
    deps: [label list] Private linked dependencies.
    externs: [scope] Set of Rust crate-dependency pairs.
    framework_dirs: [directory list] Additional framework search directories.
    frameworks: [name list] Name of frameworks that must be linked.
    friend: [label pattern list] Allow targets to include private headers.
    include_dirs: [directory list] Additional include directories.
    inputs: [file list] Additional compile-time dependencies.
    ldflags: [string list] Flags passed to the linker.
    lib_dirs: [directory list] Additional library directories.
    libs: [string list] Additional libraries to link.
    metadata: [scope] Metadata of this target.
    output_conversion: Data format for generated_file targets.
    output_dir: [directory] Directory to put output file in.
    output_extension: [string] Value to use for the output's file extension.
    output_name: [string] Name for the output file other than the default.
    output_prefix_override: [boolean] Don't use prefix for output name.
    outputs: [file list] Output files for actions and copy targets.
    partial_info_plist: [filename] Path plist from asset catalog compiler.
    pool: [string] Label of the pool used by the action.
    precompiled_header: [string] Header file to precompile.
    precompiled_header_type: [string] "gcc" or "msvc".
    precompiled_source: [file name] Source file to precompile.
    product_type: [string] Product type for Xcode projects.
    public: [file list] Declare public header files for a target.
    public_configs: [label list] Configs applied to dependents.
    public_deps: [label list] Declare public dependencies.
    rebase: [boolean] Rebase collected metadata as files.
    response_file_contents: [string list] Contents of .rsp file for actions.
    script: [file name] Script file for actions.
    sources: [file list] Source files for a target.
    testonly: [boolean] Declares a target must only be used for testing.
    visibility: [label list] A list of labels that can depend on a target.
    walk_keys: [string list] Key(s) for managing the metadata collection walk.
    write_runtime_deps: Writes the target's runtime_deps to the given path.
    xcode_extra_attributes: [scope] Extra attributes for Xcode projects.
    xcode_test_application_name: [string] Name for Xcode test target.

    Other help topics:
    all: Print all the help at once
    buildargs: How build arguments work.
    dotfile: Info about the toplevel .gn file.
    execution: Build graph and execution overview.
    grammar: Language and grammar for GN build files.
    input_conversion: Processing input from exec_script and read_file.
    label_pattern: Matching more than one label.
    labels: About labels.
    metadata_collection: About metadata and its collection.
    ninja_rules: How Ninja build rules are named.
    nogncheck: Annotating includes for checking.
    output_conversion: Specifies how to transform a value to output.
    runtime_deps: How runtime dependency computation works.
    source_expansion: Map sources to outputs for scripts.
    switches: Show available command-line switches.

ninja

ninja构建工具,编译时根据gn生成的*.ninja文件进行编译构建,ninjiad的可执行文件位置在prebuilts/build-tools/linux-x86目录里

jiajiahao@ubuntu:~/Desktop/OpenHarmony/sources/prebuilts/build-tools/linux-x86/bin$ ./ninja --help
usage: ninja [options] [targets...]

if targets are unspecified, builds the 'default' target (see manual).

options:
  --version      print ninja version ("1.10.1")
  -v, --verbose  show all command lines while building

  -C DIR   change to DIR before doing anything else
  -f FILE  specify input build file [default=build.ninja]

  -j N     run N jobs in parallel (0 means infinity) [default=18 on this system]
  -k N     keep going until N jobs fail (0 means infinity) [default=1]
  -l N     do not start new jobs if the load average is greater than N
  -n       dry run (don't run commands but act like they succeeded)

  -d MODE  enable debugging (use '-d list' to list modes)
  -t TOOL  run a subtool (use '-t list' to list subtools)
    terminates toplevel options; further flags are passed to the tool
  -w FLAG  adjust warnings (use '-w list' to list warnings)

关于deps、external_deps的使用

在添加一个模块的时候,需要在BUILD.gn中声明它的依赖,为了便于后续处理部件间依赖关系,我们将依赖分为两种------部件内依赖deps和部件间依赖external_deps。

依赖分类:

如上图所示,主要分为部件内依赖(图左)和部件间依赖(图右)。

部件内依赖: 现有模块module1属于部件part1,要添加一个属于部件part1的模块module2,module2依赖于module1,这种情况就属于部件内依赖。

部件间依赖: 现有模块module1属于部件part1,要添加一个模块module2,module2依赖于module1,module2属于部件part2。模块module2与模块module1分属于两个不同的部件,这种情况就属于部件间依赖。

部件内依赖示例:

import("//build/ohos.gni")
ohos_shared_library("module1") {
  ......
  part_name = "part1"   # 必选,所属部件名称
  ......
}

import("//build/ohos.gni")
ohos_shared_library("module2") {
  ......
  deps = [
    "module1的gn target",
  ......
 ]                        # 部件内模块依赖
part_name = "part1"       # 必选,所属部件名称
}

部件间依赖示例:

import("//build/ohos.gni")
ohos_shared_library("module1") {
  ......
  part_name = "part1"   # 必选,所属部件名称
  ......
}

import("//build/ohos.gni")
ohos_shared_library("module2") {
  ......
  external_deps = [
    "part1:module1",
  ......
  ]                      # 部件间模块依赖,这里依赖的模块必须是依赖的部件声明在inner_kits中的模块
  part_name = "part2"    # 必选,所属部件名称
}

注意:部件间依赖要写在external_deps里面,格式为"部件名:模块名"的形式,并且依赖的模块必须是依赖的部件声明在inner_kits中的模块。

查看.ninja_log文件可以知道每个模块编译的开始和结束时间

out/rk3568/.ninja_log文件记录了每个模块编译的开始和结束时间(ms),结束时间和开始时间间隔越短表示模块的编译时间越短,编译性能越高。

从左到右分别表示:start time|end time|mtime|command hash。

mtime(modify time)显示的是文件内容被修改的最后时间

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ......

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ......

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ......

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题

2.性能优化方向

3.架构方向

4.鸿蒙开发系统底层方向

5.鸿蒙音视频开发方向

6.鸿蒙车载开发方向

7.鸿蒙南向开发方向

相关推荐
学习路上_write1 分钟前
FPGA/Verilog,Quartus环境下if-else语句和case语句RT视图对比/学习记录
单片机·嵌入式硬件·qt·学习·fpga开发·github·硬件工程
非概念7 分钟前
stm32学习笔记----51单片机和stm32单片机的区别
笔记·stm32·单片机·学习·51单片机
lqj_本人1 小时前
鸿蒙next版开发:分析JS Crash(进程崩溃)
华为·harmonyos
jjjxxxhhh1231 小时前
FPGA,使用场景,相比于单片机的优势
单片机·嵌入式硬件·fpga开发
无敌最俊朗@2 小时前
stm32学习之路——八种GPIO口工作模式
c语言·stm32·单片机·学习
EterNity_TiMe_2 小时前
【论文复现】STM32设计的物联网智能鱼缸
stm32·单片机·嵌入式硬件·物联网·学习·性能优化
Harmony_QI2 小时前
鸿蒙北向开发环境安装指南
华为·harmonyos·鸿蒙
changingshow3 小时前
Arduino IDE Windows 系统 离线安装 esp32 开发板 亲测好用。
单片机·嵌入式硬件
7yewh5 小时前
嵌入式硬件杂谈(一)-推挽 开漏 高阻态 上拉电阻
驱动开发·stm32·嵌入式硬件·mcu·物联网·硬件架构·pcb工艺