写点什么

啃论文俱乐部——移植 speexdsp 到 OpenHarmony 标准系统③

作者:离北况归
  • 2022-10-12
    江苏
  • 本文字数:13252 字

    阅读完需:约 43 分钟

  • 大家好!我来自南京,在 OpenHarmony 成长计划啃论文俱乐部,与华为、软通动力、润和软件、拓维信息、深开鸿等公司一起,学习和研究操作系统技术从今年 1 月 11 日加入 OpenHarmony 俱乐部已经有接近 8 个月时间了。笔者一直在思考啃论文给我带来了些什么,通过啃论文能为 OpenHarmony 做些什么。笔者利用大二升大三暑假两个月时间移植了 Speexdsp 这个三方库到 OpenHarmony 标准系统,而关于前面的问题我似乎找到了答案,现将啃论文和三方库移植分享经验如下:

由于想要分享的内容较多,为避免读者姥爷们失去看下去的耐心,分享将以连载的方式进行。下期预告:在 OpenHarmony 的编译体系下编译 speexdsp 的 so 和测试用的可执行文件,以及编译报错的解决办法。


本期为移植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 Tool 安装包,并对解压后的文件赋权


unzip devicetool-linux-tool-3.1.0.200.zipchmod u+x devicetool-linux-tool-3.1.0.200.sh
复制代码



  • 安装 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执行这个命令会在本地生成一个文本,上边记录配置。然后再拉取代码就不用再输入账号信息了。


  • 进入 gitee 官网个人主页,个人头像下方就是 user.name


  • 再进入设置点击邮箱管理就可以得到你的 your-email-address

  • 安装 gitee 码云 repo 工具


sudo apt-get install curlsudo curl https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 -o /usr/local/bin/reposudo chmod a+x /usr/local/bin/reposudo pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests
复制代码





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


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


sudo ln -sf /usr/bin/python3 /usr/bin/pythonrepo init -u https://gitee.com/openharmony/manifest -b refs/tags/OpenHarmony-v3.2-Beta1 --no-repo-verifyrepo sync -crepo forall -c 'git lfs pull'
复制代码



3.在源码目录下执行脚本安装编译器及二进制工具下载的 prebuilts 二进制默认存放在与 OpenHarmony 同目录下的 OpenHarmony_2.0_canary_prebuilts 下。



bash build/prebuilts_download.sh
复制代码



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
复制代码


5.最后测试一下 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,编译环境没问题。

配置 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 templatesimport("//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 templatesimport("//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-declaration2.还有另外的一种方法:-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"}
复制代码


  • 第 24 行 ohos_shared_library 定义了最终生成的模块名,这里代表此模块为最终生成 libspeexdsp.z.so/动态库


如果是生成静态库 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 目录里


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 --helpusage: 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)显示的是文件内容被修改的最后时间



发布于: 刚刚阅读数: 4
用户头像

离北况归

关注

还未添加个人签名 2022-03-26 加入

OpenHarmony啃论文俱乐部PIMF团队。 位于南京一学生,可私信。

评论

发布
暂无评论
啃论文俱乐部——移植speexdsp到OpenHarmony标准系统③_OpenHarmony_离北况归_InfoQ写作社区