Hello World for gn

2023-05-26 15:31:22 浏览数 (1)

跟着v8的编译指南一轮操作下来,只知道哗啦啦的下载东西,刷刷的编译,也不知道背后干了啥,于是想了解下。搜索gn的介绍,发现中文文章大多数都是在chrome工程的基础上,添加些文件编译。而gn的quick start,也不是从零开始搭建一个gn工程,更像是如何定制chrome(v8)编译的介绍。

那么有没可能gn用在chrome系之外的工程编译呢?找到了一个6年前的项目,按其操作步骤编译,果然失败了,经过一番探索,最终调通了,这是成功的版本。

记录下探索过程中的一些收获。

gclient config

生成一个.gclient配置文件,里头记录了仓库的url。

gclient sync

这个命令(如果没有clone的话)会先clone仓库,并根据仓库根目录的DEPS配置下载依赖的仓库和做些其它自定义操作

  • deps配置了依赖的仓库,key是下载到哪个本地目录,value是仓库的地址和版本
  • hooks是一些操作,定义了某些条件下要调用的一些命令

gclient会根据当前编译情况设置些变量供DEPS文件用作触发条件,比如这个hello world会:

  • 根据host_os去下载各操作系统的对应的gn工具
  • 根据checkout_linux/checkout_x64等去下载对应的系统库和头文件

gn gen out

gn根据gn配置文件,生成ninja编译配置文件。这步碰到些坑:

gclient_args.gni找不到

代码语言:javascript复制
ERROR at //build/config/dcheck_always_on.gni:8:1: Can't load input file.

最后面在v8的DEPS中找到解决办法:往DEPS添加如下配置

代码语言:javascript复制
gclient_gn_args_file = 'build/config/gclient_args.gni'

配置后gclient sync后会生成gclient_args.gni到指定目录。

ps:这个找不到文档,如果不是有v8作为参考我是万万想不到。如果我来设计,gclient_args.gni应该有个默认输出,而build应该根据这个默认值读取文件。

sysroot找不到

代码语言:javascript复制
Missing sysroot (//build/linux/debian_wheezy_amd64-sysroot). To fix, run: build/linux/sysroot_scripts/install-sysroot.py --arch=amd64
See //build/config/sysroot.gni:88:9:
        exec_script("//build/dir_exists.py",

按其提示,最终在DEPS加hooks自动完成如上命令的执行。

ps:一般像CMake之流,会使用系统的头文件和库,这需要手动下载,否则报错的设定有点奇葩。

ninja -C out

这步是调用ninja编译项目,这也碰到几个坑:

要用libc 源码

代码语言:javascript复制
ninja: Entering directory `out'
ninja: error: '../buildtools/third_party/libc  /trunk/src/algorithm.cpp', needed by 'obj/buildtools/third_party/libc  /libc  /algorithm.o', missing and no known rule to make it

通过DEPS文件添加libc 源码下载解决。

ps:这也是和其它构建工具很不一样的地方,连这么基础的库都要下源码编译,别家一般直接链系统的。

找不到clang

代码语言:javascript复制
../third_party/llvm-build/Release Asserts/bin/clang  : not found

看路径它是用自己的clang,但该目录没有,估计要下载。在v8的花园里挖呀挖呀挖,挖到了这个:

代码语言:javascript复制
{
    # Note: On Win, this should run after win_toolchain, as it may use it.
    'name': 'clang',
    'pattern': '.',
    # clang not supported on aix
    'condition': 'host_os != "aix"',
    'action': ['python', 'tools/clang/scripts/update.py'],
  },

加入hooks这个update.py会下载clang到该目录。

ps:系统有不用,非要自己下载

终于搞定了linux编译!

一个简单的helloworld工程,最终目录竟达316M,估计都是那些libc ,clang,sysroot所占的空间。

window缺少LASTCHANGE.committime文件

想着搞定了linux,简单的helloworld应该各平台都能通了吧,结果是我想多了。

代码语言:javascript复制
IOError: [Errno 2] No such file or directory: 'D:\learn\gn1\minimal-gn-project\build\util\LASTCHANGE.committime'
ERROR at //build/timestamp.gni:31:19: Script returned non-zero exit code.

按之前gclient_args.gni的套路应该是那个地方生成的,最终在v8那找到如下hooks

代码语言:javascript复制
{
    # Update LASTCHANGE.
    'name': 'lastchange',
    'pattern': '.',
    'action': ['python', 'build/util/lastchange.py',
               '-o', 'build/util/LASTCHANGE'],
  },

ps:无力吐槽!

总结

gclient/gn这套构建系统就chrome项目自己用用好了。

0 人点赞