OpenHarmony开发——GN快速上手

2024-01-26 09:52
文章标签 快速 开发 openharmony gn

本文主要是介绍OpenHarmony开发——GN快速上手,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

最近在研究鸿蒙操作系统的开源项目OpenHarmony,该项目使用了GN+Ninja工具链进行配置,编译,于是开始研究GN如何使用。
本文的所有信息均来自GN官网和本人个人体会。

GN快速入门

使用GN

GN的主要功能是根据配置文件(.gn, BUILD.gn等)生成build.ninja文件。build.ninja类似于Makefile,不同的是由Ninja负责执行编译过程。
获取GN可执行程序。
1)源码编译。可以到官网下载源码。也可以到我的GN源码(需要5积分)
2)鸿蒙源码提供的GN可执行程序。Ubuntu下路径为[源码路径]/prebuilts/build-tools/linux-x86/bin/
将可执行程序放入PATH路径下,或将可执行程序的路径放入PATH,便可在命令行中直接使用GN。

建立构建环境

使用官网示例代码examples/simple_build,可以到官网下载,或到simple_build下载。
进入simple_build代码目录下,将…/out/build作为构建目录。

simple_build$ tree
.
├── build
│   ├── BUILDCONFIG.gn
│   ├── BUILD.gn
│   └── toolchain
│       └── BUILD.gn
├── BUILD.gn
├── hello.cc
├── hello_shared.cc
├── hello_shared.h
├── hello_static.cc
├── hello_static.h
├── README.md
└── tutorial├── README.md└── tutorial.cc
simple_build$ gn gen ../out/build
Done. Made 3 targets from 4 files in 31ms
simple_build$ tree ../out/build
../out/build
├── args.gn
├── build.ninja
├── build.ninja.d
├── obj
│   ├── hello.ninja
│   ├── hello_shared.ninja
│   └── hello_static.ninja
└── toolchain.ninja

显示构建参数

simple_build$ gn args --list ../out/build
current_cpuCurrent value (from the default) = ""(Internally set; try `gn help current_cpu`.)
current_osCurrent value (from the default) = ""(Internally set; try `gn help current_os`.)

交叉编译

设置target_os=“android”,target_cpu = “arm”

simple_build$ gn args ../out/build
##在编辑器里输入
##    target_os=“android”
##    target_cpu = "arm"
##    保存,退出
Waiting for editor on "/media/hndz-dhliu/C7968B675F10B93B/download/gn/examples/out/build/args.gn"...
Generating files...
Done. Made 3 targets from 4 files in 32mssimple_build$ gn args ../out/build --list
current_cpuCurrent value (from the default) = ""(Internally set; try `gn help current_cpu`.)
......
target_cpuCurrent value = "arm"From /media/hndz-dhliu/C7968B675F10B93B/download/gn/examples/out/build/args.gn:4Overridden from the default = ""(Internally set; try `gn help target_cpu`.)
target_osCurrent value = "android"From /media/hndz-dhliu/C7968B675F10B93B/download/gn/examples/out/build/args.gn:3Overridden from the default = ""(Internally set; try `gn help target_os`.)

添加tutorial目标

在simple_build目录下有一个tutorial目录,其下有一个tutorial.cc文件。
在tutorial目录下,添加一个BUILD.gn文件

## tutorial/BUILD.gn
executable("tutorial") {sources = ["tutorial.cc",]
}

修改simple_build下BUILD.gn文件,使其引用tutorial目录下tutorial目标。

## simple_build/BUILD.gn
group("tools") { //虚目标节点deps = [# This will expand to the name "//tutorial:tutorial" which is the full name of our new target. Run "gn help labels" for more."//tutorial",]
}

测试验证。

simple_build$ gn gen ../out/build
Done. Made 5 targets from 5 files in 35ms
simple_build$ tree ../out/build
../out/build
├── args.gn
├── build.ninja
├── build.ninja.d
├── obj
│   ├── hello.ninja
│   ├── hello_shared.ninja
│   ├── hello_static.ninja
│   └── tutorial
│       └── tutorial.ninja
└── toolchain.ninja

目标由3更新为5,产生了tutorial/ tutorial.ninja文件。
编译验证

simple_build$ ninja -C ../out/build tutorial ##表示转到../out/build tutorial目录下编译
ninja: Entering directory `../out/build'
[2/2] LINK tutorial
simple_build$ ../out/build/tutorial 
Hello from the tutorial.

BUILD.gn配置说明

simple_build/BUILD.gn
静态库hello_static配置:用static_library声明静态库,用sources声明所用的源文件。

static_library("hello_static") {sources = ["hello_static.cc","hello_static.h",]
}

可用 gn help static_library 获取static_library的详细用法。
动态库hello_shared配置:用shared_library声明动态库,用sources声明所用的源文件,用defines声明所需要的宏定义。

shared_library("hello_shared") {sources = ["hello_shared.cc","hello_shared.h",]defines = [ "HELLO_SHARED_IMPLEMENTATION" ]
}

可用 gn help shared_library 获取shared_library的详细用法。
可执行程序配置:用executable声明一个可执行程序,用sources声明该可执行程序的源文件,用deps指示所用的库文件。

executable("hello") {sources = ["hello.cc",]deps = [":hello_shared",":hello_static",]
}

测试可执行程序。

simple_build$ ninja -C ../out/build
ninja: Entering directory `../out/build'
[7/7] LINK hello
simple_build$ ../out/build/hello 
Hello, world

验证删除…/out/build/tutorial,再次编译是否重新生成tutorial

simple_build$ rm ../out/build/tutorial 
simple_build$ ninja -C ../out/build
ninja: Entering directory `../out/build'
[2/2] STAMP obj/tools.stamp
simple_build$ ls ../out/build/tutorial -la
-rwxrwxrwx 1 hndz-dhliu hndz-dhliu 8304 3月   9 13:45 ../out/build/tutorial

使用config

库使用者常常需要一些编译选项,宏定义,头文件包含路径,可以将这些内容封装到一个config变量中。
示例如下

config("my_lib_config") {defines = [ "ENABLE_DOOM_MELON" ]include_dirs = [ "//third_party/something" ]
}

使用config,将config变量添加到某个目标的configs列表中。

static_library("hello_shared") {...# Note "+=" here is usually required, see "default configs" below.configs += [":my_lib_config",]
}

如果将config变量应用到所有目标中,则将config变量添加到public_configs列表中。

static_library("hello_shared") {...public_configs = [":my_lib_config",]
}

使用默认配置

默认配置将被用到所有目标中。
可通过print函数打印默认配置。

executable("hello") {print(configs)
}

运行gn,可能打印出如下信息。

$ gn gen out
["//build:compiler_defaults", "//build:executable_ldconfig"]
Done. Made 5 targets from 5 files in 9ms

修改配置。
示例,关闭//build:no_exceptions,启用//build:exceptions

executable("hello") {...configs -= [ "//build:no_exceptions" ]  # Remove global default.configs += [ "//build:exceptions" ]  # Replace with a different one.print("The configs for the target $target_name are $configs")##打印,用来检查
}

使用参数

通过 gn help buildargs可以学习参数是如何设置的。其加载过程如下,加载系统默认参数(),加载//.gn中的default_args,加载–args命令行参数,加载工具链的参数。使用参数首先要用declare_args声明参数,并赋默认值。如果加载顺序上没被赋值,则使用默认值。

声明参数

declare_args() {enable_teleporter = trueenable_doom_melon = false
}

可通过gn help declare_args 了解declare_args详细信息。

了解GN构建过程

使用 -v 可以了解GN的详细执行流程。

simple_build$ gn gen -v ../out/build
Using source root /media/hndz-dhliu/C7968B675F10B93B/download/gn/examples/simple_build
Got dotfile /media/hndz-dhliu/C7968B675F10B93B/download/gn/examples/simple_build/.gn
Using build dir /media/hndz-dhliu/C7968B675F10B93B/download/gn/examples/out/build/
Loading //build/BUILDCONFIG.gn
Loading //BUILD.gn
Running //BUILD.gn with toolchain //build/toolchain:gcc
Defining target //:hello(//build/toolchain:gcc)
Defining target //:hello_shared(//build/toolchain:gcc)
Defining target //:hello_static(//build/toolchain:gcc)
Defining target //:tools(//build/toolchain:gcc)
Loading //build/BUILD.gn (referenced from //build/BUILDCONFIG.gn:22)
Loading //build/toolchain/BUILD.gn (referenced from //BUILD.gn:5)
Loading //tutorial/BUILD.gn (referenced from //BUILD.gn:33)
Running //build/BUILD.gn with toolchain //build/toolchain:gcc
Defining config //build:compiler_defaults(//build/toolchain:gcc)
Defining config //build:executable_ldconfig(//build/toolchain:gcc)
Running //build/toolchain/BUILD.gn with toolchain //build/toolchain:gcc
Defining toolchain //build/toolchain:gcc
Computing //:hello_static(//build/toolchain:gcc)
Computing //:hello_shared(//build/toolchain:gcc)
Computing //:hello(//build/toolchain:gcc)
Running //tutorial/BUILD.gn with toolchain //build/toolchain:gcc
Defining target //tutorial:tutorial(//build/toolchain:gcc)
Computing //tutorial:tutorial(//build/toolchain:gcc)
Computing //:tools(//build/toolchain:gcc)
Done. Made 5 targets from 5 files in 30ms

构建过程如下
1)在当前目录及其父目录查找.gn文件(即dotfile),以此作为source root
2).gn文件中buildconfig变量指示build config file路径(该文件常用来配置相关编译工具链),root变量指示source root(不指定时则为.gn所在的目录)。
3)加载build config file
4)加载source root下的BUILD.gn文件以及其引用的相关文件。
可通过gn help dotfile了解其构建过程。

查找依赖

通过 gn desc <build_dir> 可以了解一个目标的详细信息。通过 gn desc <build_dir> deps --tree 可以查找一个目标的依赖信息。

simple_build$ gn desc ../out/build //:hello
Target //:hello
type: executable
toolchain: //build/toolchain:gccvisibility*metadata{}testonlyfalsecheck_includestrueallow_circular_includes_fromsources//hello.ccpublic[All headers listed in the sources are public.]configs (in order applying, try also --tree)//build:compiler_defaults//build:executable_ldconfigoutputs/media/hndz-dhliu/C7968B675F10B93B/download/gn/examples/out/build/helloldflags-Wl,-rpath=$ORIGIN/-Wl,-rpath-link=Direct dependencies (try also "--all", "--tree", or even "--all --tree")//:hello_shared//:hello_staticexternssimple_build$ gn desc ../out/build //:hello deps --tree
//:hello_shared
//:hello_static

通过gn help desc 了解desc的更多用法。

GN文件执行脚本
参照官方文档language.md
有两种方式:
1)使用action目标类型
2)使用exec_script函数

action("run_this_guy_once") {script = "doprocessing.py"sources = [ "my_configuration.txt" ]outputs = [ "$target_gen_dir/insightful_output.txt" ]# Our script imports this Python file so we want to rebuild if it changes.inputs = [ "helper_library.py" ]# Note that we have to manually pass the sources to our script if the# script needs them as inputs.args = [ "--out", rebase_path(target_gen_dir, root_build_dir) ] +rebase_path(sources, root_build_dir)}

exec_script(filename,arguments = [],input_conversion = "",file_dependencies = [])The default script interpreter is Python ("python" on POSIX, "python.exe" or "python.bat" on Windows). This can be configured by the script_executable variable, see "gn help dotfile".
Arguments:filename:File name of script to execute. Non-absolute names will be treated as relative to the current build file.arguments: A list of strings to be passed to the script as arguments. May be unspecified or the empty list which means no arguments.input_conversion: Controls how the file is read and parsed. See "gn help io_conversion".If unspecified, defaults to the empty string which causes the script result to be discarded. exec script will return None.dependencies: (Optional) A list of files that this script reads or otherwise depends on. These dependencies will be added to the build result such that if any of them change, the build will be regenerated and the script will be re-run.Exampleall_lines = exec_script("myscript.py", [some_input], "list lines",[ rebase_path("data_file.txt", root_build_dir) ])# This example just calls the script with no arguments and discards the# result.exec_script("//foo/bar/myscript.py")

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

《鸿蒙 (OpenHarmony)开发学习手册》

入门必看:https://qr21.cn/FV7h05

  1. 应用开发导读(ArkTS)
  2. ……

HarmonyOS 概念:https://qr21.cn/FV7h05

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

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

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

开发基础知识: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.……

这篇关于OpenHarmony开发——GN快速上手的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/646432

相关文章

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

Rust中的Option枚举快速入门教程

《Rust中的Option枚举快速入门教程》Rust中的Option枚举用于表示可能不存在的值,提供了多种方法来处理这些值,避免了空指针异常,文章介绍了Option的定义、常见方法、使用场景以及注意事... 目录引言Option介绍Option的常见方法Option使用场景场景一:函数返回可能不存在的值场景

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

C#图表开发之Chart详解

《C#图表开发之Chart详解》C#中的Chart控件用于开发图表功能,具有Series和ChartArea两个重要属性,Series属性是SeriesCollection类型,包含多个Series对... 目录OverviChina编程ewSeries类总结OverviewC#中,开发图表功能的控件是Char

鸿蒙开发搭建flutter适配的开发环境

《鸿蒙开发搭建flutter适配的开发环境》文章详细介绍了在Windows系统上如何创建和运行鸿蒙Flutter项目,包括使用flutterdoctor检测环境、创建项目、编译HAP包以及在真机上运... 目录环境搭建创建运行项目打包项目总结环境搭建1.安装 DevEco Studio NEXT IDE

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设