[gn+ninja学习 0x02] GN入门示例

系统 OpenHarmony
作为开源软件,可以自己编译,也可以直接使用现有的二进制文件,官方下载地址如下。通常外网速度慢,甚至打不开。还好,gn、ninja相关的源代码可以在OpenHarmony的third party仓库下找到。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

OpenHarmony使用gn+ninja来维护开源项目的构建。之前没有接触过gn+ninja,是时候系统性的来学习下了。边学边记录下学习过程,希望对同样需要学习gn+ninja的朋友有所帮助。

这一篇,我们通过示例来学习GN的入门知识。

1、环境配置

作为开源软件,可以自己编译,也可以直接使用现有的二进制文件,官方下载地址如下。通常外网速度慢,甚至打不开。还好,gn、ninja相关的源代码可以在OpenHarmony的third party仓库下找到,见参考资料。

https://github.com/ninja-build/ninja/releases
https://chrome-infra-packages.appspot.com/p/gn/gn

搭建OpenHarmony环境后,也会自动配置gn和ninja的构建环境,这就很方便了。下载openharmony源码,使用hb编译时会自动下载gn+ninja工具时,在目录prebuilts/build-tools/linux-x86/bin下可以找到gn+ninja。更多信息请参考OpenHarmony的环境搭建文档吧。

2、GN Quick Start guide快速入门

快速入门参考了官方文档,读者也可以去阅读下原文https://gitee.com/openharmony/third_party_gn/blob/master/docs/quick_start.md。

(1)Running GN

搭建好环境后,就可以命令行运行gn命令。如下:

zhushangyuan@DESKTOP-RPE9R4O:~/openharmony$ gn help help
gn help <anything>:
Yo dawg, I heard you like help on your help so I put help on the help in the
help.
You can also use "all" as the parameter to get all help at once.
Switches
--markdown
Format output in markdown syntax.
Example
gn help --markdown all
Dump all help to stdout in markdown format.

(2)Setting up a build

GN允许你设置专有的构建目录,不同的构建目录使用不同的参数设置。设置构建目录后,当配置文件更新时,Ninja文件会自动重新生成,而不需要重新运行GN。设置构建目录使用下述命令:

gn gen out/my_build

不是随便一个目录就可以运行上述命令的,否则会报错:

ERROR Can't find source root.
I could not find a ".gn" file in the current directory or any parent,
and the --root command-line argument was not specified.

如果想练习下设置构建目录,可以切换到gn的example目录下进行尝试,如下:

cd ~/openharmony/third_party/gn/examples/simple_build/
gn gen out/my_build

(3)Passing build arguments传递构建参数

执行命令gn args --list out/my_build ,可以查询可用的参数列表及其他们的默认值。必须指定构建目录,可用参数在不同的构建目录下是不一样的。

执行命令gn args out/my_build可以为构建目录设置构建参数,该命令执行后,会打开一个编辑器,输入构建参数,类似下面:

is_component_build = true
is_debug = false

3、Step-by-step示例学习

(1)Adding a build file添加构建文件

切换到目录~/openharmony/third_party/gn/examples/simple_build/,这是最小化的GN构建示例目录。在目录下有个tutorial 目录,内有一个源文件tutorial.cc,但是有利于构建之外。在tutorial 目录下创建一个BUILD.gn文件,用于构建可执行文件target:

executable("tutorial") {
sources = [
"tutorial.cc",
]
}

然后,把构建target目标告知构建系统。simple_build目录下的BUILD.gn文件,是GN构建的入口根文件,从这里加载启动后,然后加载依赖。因此,我们在此根文件中添加引用到我们上述创建的构建target。

通常,把一个可执行文件作为另外一个可执行文件的依赖,没有意义,无法链接。我们创建一个tools组group。在GN中,group用于收集维护不会编译或者链接的依赖。如下:

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",
]
}

(2)Testing your addition验证编译

命令行进入simple_build命令,执行如下命令,可以看到会有打印输出“Hello from the tutorial.”。

gn gen out
ninja -C out tutorial
out/tutorial

(3)Declaring dependencies 声明依赖

我们再来看下examples/simple_build/BUILD.gn中的构建target的定义,⑴处定义的可执行文件构建target依赖hello_shared和hello_static,前面的冒号表示这些依赖的target在当前文件中定义,可以在下文找到。⑵处定义了一个共享库的构建target,它定义了一个函数GetSharedText(),也演示了如何使用预处理宏。⑶处定义了一个静态库的构建target,它定义了一个函数GetStaticText()。

  executable("hello") {
sources = [ "hello.cc" ]
deps = [
":hello_shared",
":hello_static",
]
}
shared_library("hello_shared") {
sources = [
"hello_shared.cc",
"hello_shared.h",
]
defines = [ "HELLO_SHARED_IMPLEMENTATION" ]
}
static_library("hello_static") {
sources = [
"hello_static.cc",
"hello_static.h",
]
}

(4)Test the binary测试运行二进制

命令行进入simple_build命令,执行如下命令,可以看到会有打印输出“Hello, world”。命令中-C指定构建目录,后面的hello也可以构建的target名称。使用命令gn ls out可以输出所有的构建target。

ninja -C out hello
out/hello

(5)Putting settings in a config使用config配置设置

使用library库的时候,经常需要编译选项、宏定义、include头文件包含等。可以把这些设置放到一个config的命名设置集里,不能放置源文件或依赖。如下:

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

为了把一个config里面的设置应用到target里,可以加到configs列表里,如注释所示,使用+=,这样默认的设置不会被覆盖。

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

一个config也能应用到所有依赖当前target的target上,只需要把config添加到public_configs 列表里,如下。public_configs 里面的设置也会应用到当前的target,不需要重复指定。

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

构建配置一般设置一些配置项,可以默认应用到所有的targe里。例如,在文件examples\simple_build\build\BUILDCONFIG.gn中,定义了如下默认configs。可以在BUILD.gn的target里使用语句“print(configs)”打印输出默认配置。

# Apply that default list to the binary target types.
set_defaults("executable") {
configs = _shared_binary_target_configs
# Executables get this additional configuration.
configs += [ "//build:executable_ldconfig" ]
}
set_defaults("static_library") {
configs = _shared_binary_target_configs
}
set_defaults("shared_library") {
configs = _shared_binary_target_configs
}
set_defaults("source_set") {
configs = _shared_binary_target_configs
}

(6)Add a new build argument添加构建参数

可以使用declare_args声明可以接受的构建参数,并提供默认值。可以使用命令查看构建参数的使用帮助gn help buildargs。

declare_args() {
enable_teleporter = true
enable_doom_melon = false
}

声明参数后,在生成构建目录时,可以在命令行指定构建参数:

gn gen out/FooBar --args="enable_doom_melon=true os=\"android\""

4、gn常用命令

  • gn gen out/dir [–args=“…”]:创建新的编译目录,会自动创建args.gn文件作为编译参数。
  • gn args --list out/dir:列出可选的编译参数。
  • gn ls out/dir:列出所有的target。
  • gn ls out/dir “//:hello_word*”:列出匹配的target。
  • gn desc out/dir “//:hello_word”:查看指定target的描述信息,包括src源码文件、依赖的lib、编译选项等。
  • gn refs out/dir 文件:查看依赖该文件的target。
  • gn refs out/dir //:hello_word:查看依赖该target的target。

注意//代表从项目根目录开始。

5、小结

我们初步了解了下构建系统、元构建系统是做什么的,了解到gn是个元构建系统,类似cmake。接下来的一篇会介绍gn入门知识、具体如何使用等等。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。

责任编辑:jianghua 来源: 51CTO开源基础软件社区
相关推荐

2022-10-26 15:33:27

GN鸿蒙

2022-10-24 14:43:31

GN语法GN

2024-01-18 15:24:06

Rust开发鸿蒙OH4.0

2021-02-02 10:13:56

鸿蒙HarmonyOS应用开发

2017-06-19 09:59:32

Python调试

2020-12-01 15:54:08

鸿蒙构建系统

2012-05-10 15:35:29

WA2110-GNH3C

2012-05-16 15:03:53

WA2110-GN

2022-06-10 14:37:24

鸿蒙操作系统

2016-12-27 14:59:50

得分函数参数

2024-01-11 16:02:38

OHOS依赖关系检查编译构建系统

2023-06-12 15:43:44

鸿蒙智能家居开发

2017-09-13 10:06:36

人工智能阿里云

2020-12-10 12:12:32

鸿蒙开发板init_lite

2023-03-17 16:38:17

gn文件图谱查询

2021-04-07 08:43:09

SpringBootRocketMQ开发技术

2017-06-22 09:45:58

阿里云GN5实例深度学习

2022-05-07 15:54:56

小熊派鸿蒙

2011-07-01 17:12:44

Qt OpenGL

2024-04-11 13:13:27

点赞
收藏

51CTO技术栈公众号