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.……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/646754.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

交换机跨VLAN交换数据ip跳转分析(不一定对)

在网上看到这样一个实验&#xff1a; 交换机1、交换机2分别连接到一台防火墙上&#xff0c;要求使VLAN 2、VLAN3、VLAN5、VLAN6中的终端可互相访问。 拓补 参考链接 【数通网络交换基础梳理2】三层设备、网关、ARP表、VLAN、路由表及跨网段路由下一跳转发原理_网管型交的机…

DC60V降压恒流 3A电流 直播美颜补光灯专用降压IC

DC60V降压恒流3A电流直播美颜补光灯专用降压IC 随着直播行业的兴起&#xff0c;美颜补光灯成为了直播中不可或缺的设备之一。然而&#xff0c;不同的直播设备和场景需要不同的灯光效果&#xff0c;因此需要一款能够提供稳定、高质量照明的补光灯。其中&#xff0c;DC60V降压恒流…

CentOS7自动备份数据库到git

虽然数据库没什么数据&#xff0c;但是有就是珍贵的啦&#xff0c;为了服务器什么的无了&#xff0c;所以还是要自动备份一下比较好。 Open备忘第一页 步骤 在Gitee&#xff08;github&#xff09;上创建一个私有仓库Gitee&#xff08;github&#xff09;配置好服务器的ssh在服…

论文阅读:Vary-toy论文阅读笔记

目录 引言整体结构图方法介绍训练vision vocabulary阶段PDF数据目标检测数据 训练Vary-toy阶段Vary-toy结构数据集情况 引言 论文&#xff1a;Small Language Model Meets with Reinforced Vision Vocabulary Paper | Github | Demo 说来也巧&#xff0c;之前在写论文阅读&…

微信小程序开发如何实现圆形按钮/圆角按钮

圆形按钮&#xff1a; 显示&#xff1a; 实现 .wxml <view style"width: 100%;height:200rpx;display: flex; align-items: center;justify-content: center;"><view style"width:20px; height:20px; border-radius: 50%; background-color: red; t…

134. 加油站 - 力扣(LeetCode)

题目描述 在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。 给定两个整数数组 gas 和…

SHA加密在实际应用中的优势与局限

SHA加密算法简介 SHA&#xff08;Secure Hash Algorithm&#xff09;加密算法是一种单向加密算法&#xff0c;常用于加密数据的完整性校验和加密签名。它是由美国国家安全局&#xff08;NSA&#xff09;设计并广泛应用于各种安全场景。SHA加密算法具有较高的安全性和可靠性&…

线性代数速通

二---矩阵 逆矩阵 抽象矩阵求逆 数字型矩阵求逆 二阶矩阵求逆秒杀 解矩阵方程 方阵 伴随矩阵 三---向量组的线性相关性 线性表示 数字型向量组 线性相关性判断 抽象型向量组 线性相关性判断 向量组的秩与极大无关组 四---线性方程组 齐次方程组 基础解系 通解 非齐…

定制工厂实时数据采集系统 优秀智能制造信息系统服务

工业数据采集是指通过传感器、仪表等设备将工业生产过程中的各种数据进行采集和记录,以便进行数据分析、监控和优化。但现状却是引入的各自动化设备、仪器等各自为政&#xff0c;或者进显示检测数据&#xff0c;难以实现数据连通&#xff0c;难以统一处理&#xff0c;定制的数据…

并查集与图

并查集与图 一、并查集概念实现原理代码实现查找根节点合并两颗树判断是否是同一棵树树的数量 二、图的基本概念定义分类完全图顶点的度连通图 三、图的存储结构分类邻接表邻接表的结构代码实现 邻接矩阵代码实现 四、图的遍历方式广度优先深度优先 五、最小生成树概念Kruskal算…

网络原理-初识(2)

协议分层 对于网络协议来说,往往分成几个层次进行定义. 网络通信的过程中,需要涉及到的细节,其实非常多.如果要有一个协议来完成网络通信,就需要约定好方方面面的内容,导致非常复杂. 而如果拆分的话,就十分复杂,庞大,因此需要分层. 什么是协议分层 即只有相邻的层次可以沟通,…

代码随想录 Leetcode102. 二叉树的层序遍历

题目&#xff1a; 代码(首刷看解析 2024年1月24日&#xff09;&#xff1a; class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> res;if(root nullptr) return res;queue<TreeNode*> que;TreeNode…

蓝桥杯备战——5.动态数码管扫描

1.分析原理图 经查阅说明书得知数码管为共阳极&#xff0c;共阳端口接到了U8,而段码接到了U7。 如果需要选中U8,我们只需要将P250;P261;P271; 如果需要选中U7,我们只需要将P251;P261;P271; 2.代码示例 void Delay1ms() //12.000MHz {unsigned char data i, j;i 12;j 169;…

【2024】新建mysql数据库,如何选择字符集和排序规则

如何使用 Navicat 新建 MySQL 数据库&#xff0c;并选择字符集与排序规则 如何使用 Navicat 新建 MySQL 数据库并选择字符集与排序规则1. 开始之前2. 新建数据库步骤 1: 打开 Navicat步骤 2: 创建新数据库步骤 3: 填写数据库名称 常见的字符集和排序规则及其选择场景1. 字符集&…

7.前端--CSS-复合选择器

1.什么是复合选择器 复合选择器是由两个或多个基础选择器&#xff0c;通过不同的方式组合而成的&#xff0c;可以更准确、更高效的选择目标元素&#xff08;标签&#xff09; 常用的复合选择器包括&#xff1a;后代选择器、子选择器、并集选择器、伪类选择器等等 2.后代选择器 …

flink基础概念之什么是时间语义

什么是时间语义 Flink支持三种不同的时间语义&#xff0c;以便处理流式数据中的事件时间、处理时间和摄入时间。 1. 处理时间&#xff08;Processing Time&#xff09; 处理时间的概念非常简单&#xff0c;就是指执行处理操作的机器的系统时间。 在这种时间语义下处理窗口非…

接口自动化测试实践

众所周知&#xff0c;接口自动化测试有着如下特点&#xff1a; 低投入&#xff0c;高产出。 比较容易实现自动化。 和UI自动化测试相比更加稳定。 如何做好一个接口自动化测试项目呢&#xff1f; 我认为&#xff0c;一个“好的”自动化测试项目&#xff0c;需要从“时间”…

05-Seata下SQL使用限制

不支持 SQL 嵌套不支持多表复杂 SQL(自1.6.0版本&#xff0c;MySQL支持UPDATE JOIN语句&#xff0c;详情请看不支持存储过程、触发器部分数据库不支持批量更新&#xff0c;在使用 MySQL、Mariadb、PostgreSQL9.6作为数据库时支持批量&#xff0c;批量更新方式如下以 Java 为例 …

掌握大语言模型技术: 推理优化

掌握大语言模型技术_推理优化 堆叠 Transformer 层来创建大型模型可以带来更好的准确性、少样本学习能力&#xff0c;甚至在各种语言任务上具有接近人类的涌现能力。 这些基础模型的训练成本很高&#xff0c;并且在推理过程中可能会占用大量内存和计算资源&#xff08;经常性成…

C++:反向迭代器-reverse_iterator

目录 1.关于反向迭代器 2.反向迭代器的成员函数 1.构造 2.base 3.operator* 4.operator 5.operator-- 6.operator-> 7.operator[] 3.反向迭代器的模拟实现 小结 1.关于反向迭代器 在C中&#xff0c;可以使用反向迭代器来逆序遍历容器中的元素。反向迭代器是通过…