跟着v8的编译指南一轮操作下来,只知道哗啦啦的下载东西,刷刷的编译,也不知道背后干了啥,于是想了解下。搜索gn的介绍,发现中文文章大多数都是在chrome工程的基础上,添加些文件编译。而gn的quick start,也不是从零开始搭建一个gn工程,更像是如何定制chrome(v8)编译的介绍。
那么有没可能gn用在chrome系之外的工程编译呢?找到了一个6年前的项目,按其操作步骤编译,果然失败了,经过一番探索,最终调通了,这是成功的版本。
记录下探索过程中的一些收获。
生成一个.gclient配置文件,里头记录了仓库的url。
这个命令(如果没有clone的话)会先clone仓库,并根据仓库根目录的DEPS配置下载依赖的仓库和做些其它自定义操作
gclient会根据当前编译情况设置些变量供DEPS文件用作触发条件,比如这个hello world会:
gn根据gn配置文件,生成ninja编译配置文件。这步碰到些坑:
gclient_args.gni找不到
ERROR at //build/config/dcheck_always_on.gni:8:1: Can't load input file.
最后面在v8的DEPS中找到解决办法:往DEPS添加如下配置
gclient_gn_args_file = 'build/config/gclient_args.gni'
配置后gclient sync后会生成gclient_args.gni到指定目录。
ps:这个找不到文档,如果不是有v8作为参考我是万万想不到。如果我来设计,gclient_args.gni应该有个默认输出,而build应该根据这个默认值读取文件。
sysroot找不到
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编译项目,这也碰到几个坑:
要用libc++源码
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
../third_party/llvm-build/Release+Asserts/bin/clang++: not found
看路径它是用自己的clang,但该目录没有,估计要下载。在v8的花园里挖呀挖呀挖,挖到了这个:
{
# 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应该各平台都能通了吧,结果是我想多了。
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
{
# Update LASTCHANGE.
'name': 'lastchange',
'pattern': '.',
'action': ['python', 'build/util/lastchange.py',
'-o', 'build/util/LASTCHANGE'],
},
ps:无力吐槽!
gclient/gn这套构建系统就chrome项目自己用用好了。