鸿蒙南向开发——GN快速入门指南
运行GN(Generate Ninja)
运行gn
,你只需从命令行运行gn
,对于大型项目,GN是与源码一起的。
- 对于Chromium和基于Chromium的项目,有一个在
depot_tools
中的脚本,它需要加入到你的PATH环境变量中。该脚本将在包含当前目录的源码树中找到二进制文件并运行它。 - 对于Fuchsia树内开发,运行
fx gn ...
,它将找到正确的GN二进制文件,并使用给定的参数运行它。
设置一个构建
与其他一些构建系统不同,在GN中你可以设置你自己的构建目录,和你想要的设置。这让你可以根据需要维护不同的构建,可以根据自己的需要并行维护不同的构建。
一旦你生成了一个构建目录,ninja
文件将被自动生成,如果你在该目录下进行构建时,文件已经过期,ninja
则会自动重新生成,所以你不必重新运行gn
。
建立一个构建目录:
gn gen out/my_build
配置构建参数
在你的构建目录上运行设置构建参数:
gn args out/my_build
这将弹出一个编辑器,在该文件中输入build args,像这样:
is_component_build = true
is_debug = false
可用的变量将取决于你的构建,你可以看到可用参数的列表和它们的默认值。
通过键入:
gn args --list out/my_build
可以看到可用的参数列表和默认值,这个命令必须指定编译目录,因为不同的目录有不同的参数值。
Chrome的开发者也可以阅读Chrome特有的构建配置说明以了解更多信息。
交叉编译至目标操作系统或架构
运行 gn args out/Default
(根据需要替换成你的构建目录),然后为常见的交叉编译选项添加以下一行或多行:
target_os = "chromeos"
target_os = "android"target_cpu = "arm"
target_cpu = "x86"
target_cpu = "x64"
更多信息请参见 GN cross compiles 。
添加BUILD.gn的详细步骤
添加一个构建文件
转到examples/simple_build
目录,这是一个最小的GN仓库的root目录。
在该目录中,有一个tutorial
目录。这里已经有一个tutorial.cc
文件,但没有与构建挂钩。在该目录中为我们的新目标创建一个新的BUILD.gn
文件,用于我们的新目标:
executable("tutorial") {sources = ["tutorial.cc"]
}
现在我们只需要告诉编译器这个新的目标。
打开目录(simple_build
)下的BUILD.gn
文件,GN从加载这个根文件,然后从这里开始加载所有的依赖项,所以我们只需要在这里添加对这个文件中的新目标的引用。
你可以把我们的新目标作为一个依赖关系加入到现有的目标中去,但把一个可执行文件作为依赖关系并没有什么意义。通常情况下,将一个可执行文件作为另一个可执行文件的依赖项是没有意义的(它们不能被链接)。
所以让我们做一个 tools group
组。在GN中,一个group
只是一个依赖关系的集合,没有编译或链接:
group("tools") {deps = [# 这将扩展到"//tutorial:tutorial "这个名字,这是新目标的全名# 新目标,运行 "gn help labels "可以获得更多信息# ‘//’双斜杠代表的是从source-root目录开始的路径,也可以用绝对路径来写,比如'/usr/local/foo:bar'"//tutorial"]
}
执行
gn help labels
可以看到help的详细的解释,关于如何添加子目录的目标到BUILD.gn里面。
测试你的添加
从simple_build
目录下的命令行:
$ gn gen out$ ninja -C out tutorialninja: Entering directory `out'[2/2] LINK tutorial
执行./out/tutorial
你应该看到 Hello from the tutorial.
输出到控制台。
题外话:GN
鼓励静态库的目标名称不是全局唯一的。要建立一个这样的库,你可以把标签和它的路径(但没有前面的//
)给ninja
:
ninja -C out some/path/to/target:my_target
所以前面的tutorial可以是:
$ ninja -C out tutorial:tutorialninja: Entering directory `out'ninja: no work to do.
声明依赖性
让我们看看在下列文件examples/simple_build/BUILD.gn
中定义的目标。这里有一个静态库定义了一个函数,GetStaticText()
:
static_library("hello_static") {sources = [ "hello_static.cc", "hello_static.h", ] }
还有一个共享库,定义了一个函数GetSharedText()
:
shared_library("hello_shared") { sources = [ "hello_shared.cc", "hello_shared.h", ] defines = [ "HELLO_SHARED_IMPLEMENTATION" ]}
这也说明了如何为一个目标设置预处理程序的定义,要设置多个以上的定义或赋值,请使用这种形式:
defines = [ "HELLO_SHARED_IMPLEMENTATION", "ENABLE_DOOM_MELON=0",]
现在我们来看看依赖这两个库的可执行文件:
executable("hello") { sources = [ "hello.cc", ] # 以冒号开头的标签指的是当前BUILD.gn文件中的标签 deps = [ ":hello_shared", ":hello_static", ]}
这个可执行文件包括一个源文件,并依赖于前面的两个库,以冒号开头的标签指的是当前BUILD.gn文件中具有该名称的目标。
测试二进制文件
在simple_build
目录下的命令行中:
ninja -C out helloout/hello
注意,你不需要重新运行GN。当任何构建文件发生变化时,GN会自动重新构建
ninja文件。因为ninja在开始执行时打印出[1/1] Regenerating ninja files
时,你就知道这个发生了。
将设置放在config
中
一个库的用户经常需要用到compile flags
、 defines
、include directories
,要做到这一点,把所有这些设置放到一个 "config "中就可以,这是一个命名的设置集合(但不包括源和依赖关系)。
config("my_lib_config") { defines = [ "ENABLE_DOOM_MELON" ] 。 include_dirs = [ "//third_party/something" ] 。}
要将一个配置的设置应用于目标,请将其添加到configs
列表中。
static_library("Hello_shared") { ... # 注意这里的 "+="通常是必须的,见下面的 "默认配置"。 configs += [ ":my_lib_config", ]}
一个配置可以应用于所有依赖当前配置的目标,只要把它的标签放在public_configs
列表中。
static_library("Hello_shared") { ... public_configs = [ ":my_lib_config", ]}
public_configs
也适用于当前的目标,所以不需要在两个地方都列出一个配置。
默认配置
构建配置将设置一些默认适用于每个target
的设置。
默认情况下,这些通常会被设置为默认的配置列表。你可以用print
命令看到 你可以使用print
命令看到这一点,这对调试很有用:
executable("hello") { print(configs)}
运行GN将打印类似的东西:
$ gn gen out["//build:compiler_defaults", "//build:executable_ldconfig"]
目标可以修改这个列表以改变其默认值。
例如,构建设置可能会通过添加no_exceptions
配置来默认关闭异常,但目标可以通过用不同的配置来重新启用它们:
executable("hello") { ... configs -= [ "//build:no_exceptions" ] # 删除全局默认。 configs += [ "//build:exceptions" ] # 用一个不同的来代替.}
我们上面的打印命令也可以用字符串插值来表达,这是一种将数值转换成字符串的方法。它使用符号"$"来指代一个变量。
print("The configs for the target $target_name are $configs")
执行ninja -C out hello
$ ninja -C out helloninja: Entering directory `out'[0/1] Regenerating ninja filesThe configs for the target hello are ["//build:compiler_defaults", "//build:executable_ldconfig"]ninja: no work to do.
添加一个新的构建参数
你可以通过declare_args
声明你接受哪些参数并指定默认值。
declare_args() { enable_teleporter = true enable_doom_melon = false}
参见gn help buildargs
以了解其工作原理。
参见gn help declare_args
以了解声明参数的具体细节。
在一个给定的范围内多次声明一个参数是一个错误,所以在确定参数的范围和命名时应该谨慎。
不知道发生了什么?
你可以在verbose模式下运行GN,以看到很多详细过程,使用-v
参数就可以:
$ gn gen out -vUsing source root /home/hui/disk4t/codes/gn/examples/simple_buildGot dotfile /home/hui/disk4t/codes/gn/examples/simple_build/.gnUsing build dir //out/Loading //build/BUILDCONFIG.gnLoading //BUILD.gnRunning //BUILD.gn with toolchain //build/toolchain:gccThe configs for the target hello are ["//build:compiler_defaults", "//build:executable_ldconfig"]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:34)Running //build/BUILD.gn with toolchain //build/toolchain:gccRunning //tutorial/BUILD.gn with toolchain //build/toolchain:gccDefining config //build:compiler_defaults(//build/toolchain:gcc)Defining target //tutorial:tutorial(//build/toolchain:gcc)Defining config //build:executable_ldconfig(//build/toolchain:gcc)Running //build/toolchain/BUILD.gn with toolchain //build/toolchain:gccDefining toolchain //build/toolchain:gccComputing //:hello_shared(//build/toolchain:gcc)Computing //:hello_static(//build/toolchain:gcc)Computing //:hello(//build/toolchain:gcc)Computing //tutorial:tutorial(//build/toolchain:gcc)Computing //:tools(//build/toolchain:gcc)Done. Made 5 targets from 5 files in 5ms
"desc "命令
你可以运行gn desc <build_dir> <targetname>
来获取有关
一个给定的目标。
gn desc out //tutorial:tutorialThe configs for the target hello are ["//build:compiler_defaults", "//build:executable_ldconfig"]Target //tutorial:tutorialtype: executabletoolchain: //build/toolchain:gcc...
获取ldflags
信息
$ gn desc out //tutorial:tutorial ldflagsThe configs for the target hello are ["//build:compiler_defaults", "//build:executable_ldconfig"]-Wl,-rpath=$ORIGIN/-Wl,-rpath-link=
假设你想知道你的TWO_PEOPLE
定义来自哪里:
gn desc out/Default //foo/bar:say_hello defines --blame...lots of other stuff omitted... From //foo/bar:hello_config (Added //foo/bar/BUILD.gn:12) TWO_PEOPLE
另一个特别有趣的变体:
gn desc out/Default //base:base_i18n deps --tree
更多信息见gn help desc
。
附:gn labels
关于标签
所有可以参与依赖关系的图(目标、配置和工具链)都由标签来识别,一个常见的标签看起来像:
//base/test:test_support
这个例子包括一个source-root绝对路径、一个冒号和一个target,这意味着要在 "base/test/BUILD.gn "中寻找名为 "test_support "的目标。 如果有必要,你也可以指定系统的绝对路径。通常情况下,这样的路径会通过构建参数来指定,所以开发者可以指定组件在他们系统中的位置。
/usr/local/foo:bar (Posix)/C:/Program Files/MyLibs:bar (Windows)
工具链
一个规范的标签包括正在使用的工具链的标签。通常情况下,工具链标签隐含地继承自当前的执行环境,但你可以覆盖它以指定跨工具链的依赖关系。
//base/test:test_support(//build/toolchain/win:msvc)
这里 GN 将在文件"//build/toolchain/win "中寻找名为 "msvc "的工具链定义,以知道如何编译这个目标。
相对标签
如果你想引用同一构建文件中的东西,你可以省略路径名称,只用冒号开头。这种格式被推荐用于同文件中的标签引用。
:base
标签可以被指定为相对于当前目录的标签。从风格上看,我们更倾向于对所有非文件本地的引用使用绝对路径,除非一个构建文件需要在不同的环境下运行(比如一个项目既需要独立运行,又需要拉到目录层次中不同位置的其他项目中)。
source/plugin:myplugin.../net:url_request
隐式名称
如果一个名字没有被指定,它将继承目录名称。从风格上看,我们倾向于在可能的情况下省略冒号和名称。
//net -> //net:net//tools/gn -> //tools/gn:gn
为了能让大家更好的学习鸿蒙 (OpenHarmony) 开发技术,这边特意整理了《鸿蒙 (OpenHarmony)开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05
《鸿蒙 (OpenHarmony)开发学习手册》
入门必看:https://qr21.cn/FV7h05
- 应用开发导读(ArkTS)
- ……
HarmonyOS 概念:https://qr21.cn/FV7h05
- 系统定义
- 技术架构
- 技术特性
- 系统安全
如何快速入门?:https://qr21.cn/FV7h05
- 基本概念
- 构建第一个ArkTS应用
- 构建第一个JS应用
- ……
开发基础知识:https://qr21.cn/FV7h05
- 应用基础知识
- 配置文件
- 应用数据管理
- 应用安全管理
- 应用隐私保护
- 三方应用调用管控机制
- 资源分类与访问
- 学习ArkTS语言
- ……
基于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.……
相关文章:

鸿蒙南向开发——GN快速入门指南
运行GN(Generate Ninja) 运行gn,你只需从命令行运行gn,对于大型项目,GN是与源码一起的。 对于Chromium和基于Chromium的项目,有一个在depot_tools中的脚本,它需要加入到你的PATH环境变量中。该脚本将在包含当前目录的…...
PyCharm常用快捷键和设置
Ctrl Space 基本的代码完成(类、方法、属性) Ctrl Alt Space 快速导入任意类 Ctrl Shift Enter 语句完成 Ctrl P 参数信息(在方法中调用参数) Ctrl Q 快速查看文档 F1 外部文档 Shift F1 外部文档…...

Unity - 调节camera物理相机参数(HDRP)
在 “Hierarchy” 右键 -> Volume -> Global Volume new 一个 profile, 设置Mode为Pysical Camera 再点击camera组件,这时候设置 ISO、Shutter Speed、Aperture等参数值还会有效。...

@JsonIgnore的使用及相关问题的解决
目录 1 前言 2 对比及其使用方法 3 遇到的相关问题及解决方法 1 前言 在我们编写的后端项目中,有时候可能需要将某个实体类以JSON格式传送给前端,但是其中可能有部分内容我们并不想传送,这时候我们选择将这部分内容变成Null,这…...

万户 ezOFFICE SendFileCheckTemplateEdit.jsp SQL注入漏洞
0x01 产品简介 万户OA ezoffice是万户网络协同办公产品多年来一直将主要精力致力于中高端市场的一款OA协同办公软件产品,统一的基础管理平台,实现用户数据统一管理、权限统一分配、身份统一认证。统一规划门户网站群和协同办公平台,将外网信息维护、客户服务、互动交流和日…...

自建DNS劫持服务器,纯内网劫持PS5,屏蔽更新,自动hen
背景:目前PS5首次折腾必须要连外网,还要改DNS,除非使用ESP8266/32, 本文的方法是完全不改DNS,不使用ESP8266,不连接外网的情况下自动折腾 能实现什么: 1.折腾全程不连接外网 2.完全自建hen服务器ÿ…...

C语言王道第八周一题
Description 初始化顺序表(顺序表中元素为整型),里边的元素是 1,2,3,然后通过 scanf 读取一个元素(假如插入的是 6),插入到第 2 个位置,打印输出顺序表,每个 元素占 3 个…...

探索1688店铺所有商品API接口:一键获取海量数据,开启商业智能新篇章
1688店铺所有商品API接口技术详解 一、概述 1688店铺所有商品API接口是阿里巴巴提供的一套应用程序接口,允许第三方开发者获取指定1688店铺下的所有商品信息。通过使用这个接口,开发者可以获取到店铺内所有商品的列表、详情、属性等信息,从…...

使用Win32API实现贪吃蛇小游戏
目录 C语言贪吃蛇项目 基本功能 需要的基础内容 Win32API 介绍 控制台程序部分指令 设置控制台窗口的长宽 设置控制台的名字 控制台在屏幕上的坐标位置结构体COORD 检索指定标准设备的句柄(标准输入、标准输出或标准错误) 光标信息结构体类型CONSOLE_CUR…...
力扣0114——二叉树展开为链表
[二叉树展开为链表] 难度:中等 题目描述 给你二叉树的根结点 root ,请你将它展开为一个单链表: 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。展开后的单…...
FPGA硬件架构
1.Xilinx FPGA是异构计算平台(所谓异构,就是有很多不同的部分组成):CLB,BRAM,DSP 2. 软核: 把经过功能验证的、可综合的、实现后电路结构总门数在五千门以上的Verilog HDL模型称为软核(soft core)。 硬核: 把在某一…...
spring boot 嵌入chatGPT步骤
一、需要良好的网络 二、需要在OpenAI官网https://openai.com/注册用户,并获取一个api-key,sk开头的 验证是否可用网站:http://tools.lbbit.top/check_key_valid/ 三、spring boot 配置文件 openai.proxyHost127.0.0.1 openai.proxyPort7890…...

博云科技与中科可控全面合作,探索前沿金融科技新机遇
2024年1月26日,博云科技与中科可控在昆山高新区成功举办合作签约仪式。昆山市委常委、昆山高新区党工委书记孙道寻、中科可控董事长聂华、博云科技董事长花磊等领导出席了本次签约仪式。 中科可控将利用其在先进计算和智造领域的优势,为博云科技提供有关…...

十一、常用API——练习
常用API——练习 练习1 键盘录入:练习2 算法水题:练习3 算法水题:练习4 算法水题:练习5 算法水题: 练习1 键盘录入: 键盘录入一些1~100之间的整数,并添加到集合中。 直到集合中所有数据和超过2…...

基于ssm和微信小程序的健身房私教预约管理系统
文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式 🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 &…...
微服务架构
微服务(Microservices)是一种将应用程序作为独立服务套件的架构风格,这些服务围绕业务功能构建,可以通过网络调用进行交互。微服务架构使得可以独立开发、测试、部署和缩放各个服务。 微服务的核心原则包括: 高内聚&…...

山体滑坡在线安全监测预警系统(解决方案)
在近年来,随着全球气候变化的影响,山体滑坡等自然灾害频发,给人们的生命财产安全带来了严重威胁。为了有效预防和减少山体滑坡带来的危害,许多地方开始在山上安装山体滑坡在线安全监测预警系统(解决方案)。…...

StarRocks -- 基础概念(数据模型及分区分桶)
1. 数据模型 StarRocks提供四种数据模型: Duplicate Key, Aggregate Key, Unique Key, Primary Key 1.1 Duplicate Key 适用场景: 分析原始数据,如原始日志和原始操作记录。可以使用多种方法查询数据,不受预聚合方法的限制。加…...

Unity 状态模式(实例详解)
文章目录 简介示例1:基础角色状态切换示例2:添加更多角色状态示例3:战斗状态示例4:动画同步状态示例5:状态机管理器示例6:状态间转换的条件触发示例7:多态行为与上下文类 简介 Unity 中的状态模…...

力扣hot100 分割回文串 集合 dfs
Problem: 131. 分割回文串 文章目录 思路Code💖 DP预处理版 思路 👨🏫 参考题解 Code import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List;public class Solution {int n;//字符…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

nnUNet V2修改网络——暴力替换网络为UNet++
更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...