当前位置: 首页 > 科技观察

【gn+ninja学习0x02】GN入门示例

时间:2023-03-13 14:21:38 科技观察

了解更多开源请访问:开源基础软件社区https://ost.51cto.comOpenHarmony使用gn+ninja为开源项目维护构建.之前没接触过gn+ninja,是时候系统学习一下了。边学习边记录学习过程,希望对同样需要学习gn+ninja的朋友有所帮助。在本文中,我们通过实例来学习GN的入门知识。1.环境配置作为开源软件,可以自行编译,也可以直接使用已有的二进制文件。官方下载地址如下。通常外部网络很慢,甚至不可用。幸运的是,gn和ninja相关的源代码可以在OpenHarmony的第三方存储库下找到,请参阅参考资料。https://github.com/ninja-build/ninja/releaseshttps://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快速入门指南快速入门参考官方文档,读者也可阅读原文https://gitee.com/openharmony/third_party_gn/blob/master/docs/quick_start.md。(1)运行GN搭建好环境后,就可以在命令行运行gn命令了。如下:zhushangyuan@DESKTOP-RPE9R4O:~/openharmony$gnhelphelpgnhelp:哟老哥,听说你喜欢helponyourhelp所以我把helponhelp放在了help里面。也可以使用“all”作为参数,一次性获取所有帮助。切换--markdown以markdown语法格式输出。示例gnhelp--markdownall将所有帮助以markdown格式转储到stdout。(2)设置buildGN可以设置一个专门的构建目录,不同的构建目录使用不同的参数设置。设置构建目录后,更新配置文件时会自动重新生成Ninja文件,无需重新运行GN。使用以下命令设置构建目录:gngenout/my_build可以不带任何目录运行以上命令,否则会报错:ERRORCan'tfindsourceroot.Icouldnotfinda".gn"file在当前目录或任何父目录中,并且未指定--root命令行参数。如果想练习设置build目录,可以切换到gn的example目录下试试,如下:cd~/openharmony/third_party/gn/examples/simple_build/gngenout/my_build(3)传递构建参数Pass构建参数执行命令gnargs--listout/my_build,可以查询可用参数列表及其默认值。必须指定构建目录,不同的构建目录可用参数不同。执行命令gnargsout/my_build为构建目录设置构建参数。命令执行后,会打开一个编辑器,输入构建参数,类似如下:is_component_build=trueis_debug=false3、循序渐进的例子学习(一)添加构建文件Addbuildfiles进入目录~/openharmony/third_party/gn/examples/simple_build/,这是最小的GN构建示例目录。目录下有个tutorial目录,里面有个源文件tutorial.cc,但是不利于构建。在教程目录中创建一个BUILD.gn文件以构建可执行目标:executable("tutorial"){sources=["tutorial.cc",]}然后,将target目标告知构建系统。simple_build目录下的BUILD.gn文件是GN构建的入口根文件。从这里加载并开始后,再加载依赖项。因此,我们在这个根文件中添加了对上面创建的构建目标的引用。通常,将一个可执行文件作为另一个可执行文件的依赖项并且不能链接是没有意义的。我们创建一个工具组组。在GN中,group用于收集和维护不会被编译或链接的依赖项。如下:group("tools"){deps=[#这将扩展为名称“//tutorial:tutorial”,这是我们新目标的全名。运行“gnhelplabels”以获得更多信息。"//tutorial",]}(2)测试你的添加验证编译命令行输入simple_build命令,执行下面的命令,可以看到会打印出“Hellofromthetutorial.”。gngenoutninja-Couttutorialout/tutorial(3)声明依赖项声明依赖项让我们看一下examples/simple_build/BUILD.gn中构建目标的定义。(1)中定义的可执行文件构建目标依赖于hello_shared和hello_static。前面的冒号表示这些依赖目标是在当前文件中定义的,可以在下面找到。⑵定义了一个共享库构建目标,其中定义了一个函数Ge??tSharedText(),同时也演示了如何使用预处理宏。⑶定义了一个静态库构建目标,其中定义了一个函数Ge??tStaticText()。⑴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)测试二进制测试运行二进制命令行输入simple_build命令,执行如下命令,可以看到会打印出“Hello,world”。命令中-C指定构建目录,后面的hello也可以是构建的目标名称。使用命令gnlsout输出所有构建目标。ninja-Couthelloout/hello(5)将设置放在一个config中使用config配置设置使用library库时,往往需要编译选项、宏定义、include头文件等。这些设置可以放在一组名为config的设置中,不能放置源文件或依赖项。如下:config("my_lib_config"){defines=["ENABLE_DOOM_MELON"]include_dirs=["//third_party/something"]}为了将配置中的设置应用到目标,可以将其添加到配置列表,如注释中所示,使用+=,这样默认设置就不会被覆盖。static_library("hello_shared"){...#注意这里的“+=”通常是必需的,参见下面的“默认配置”。configs+=[":my_lib_config",]}一个config也可以应用到所有依赖当前target上的target上,只需将config添加到public_configs列表即可,如下。public_configs中的设置也会应用于当前目标,无需重复指定。static_library("hello_shared"){...public_configs=[":my_lib_config",]}Buildconfiguration一般设置一些配置项,默认可以应用于所有target。例如,在文件examples\simple_build\build\BUILDCONFIG.gn中,定义了以下默认配置。您可以在BUILD.gn的目标中使用语句“print(configs)”来打印出默认配置。#将该默认列表应用于二进制目标类型。set_defaults("executable"){configs=_shared_binary_target_configs#可执行文件获得这个附加配置。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)添加一个新的构建参数您可以使用declare_args来声明可接受的构建参数并提供默认值。您可以使用命令gnhelpbuildargs查看构建参数的使用帮助。declare_args(){enable_teleporter=trueenable_doom_melon=false}声明参数后,在生成构建目录时,可以在命令行指定构建参数:gngenout/FooBar--args="enable_doom_melon=trueos=\"android\""4.常用gn命令gngenout/dir[–args="..."]:新建编译目录,args.gn文件会自动创建为编译参数。gnargs--listout/dir:列出可选的编译参数。gnlsout/dir:列出所有目标。gnlsout/dir"//:hello_word*":列出匹配的目标。gndescout/dir"//:hello_word":查看指定target的描述信息,包括src源码文件、依赖库、编译选项等。gnrefsout/dir文件:查看依赖于该文件的目标。gnrefsout/dir//:hello_word:查看依赖这个target的target。注意//表示从项目根目录开始。5.总结我们初步了解下构建系统和元构建系统是干什么的,了解到gn是一个元构建系统,类似于cmake。下一篇文章将介绍gn入门知识,如何使用等等。了解更多开源知识,请访问:开源基础软件社区https://ost.51cto.com。