八卦一下Starlark语言

八卦一下Starlark语言

编译移植TensorFlow时用到Bazel这一构建工具,Bazel用Starlark语法来编写WORKSPACE/BUILD文件,它们是类似于Make中的makeifle、CMake中的CMakeLists的存在。

来源:https://blog.bazel.build/2017/03/21/design-of-skylark.html

Starlark语言简史

早些年google用make+makefile构建代码,后来代码多了,发现make不适合(反正我是觉得makefile语法太怪异了,之前看ucore/JOS操作系统内核时候就很慌)。

一个临时办法是手写一个描述文件BUILD,然后用Python生成makefile文件(沿着这种思路,考虑VC/gcc/XCode等多种平台,就是cmake了)。

但是其实Make更大问题是速度太慢,于是google搞了个Blaze,开源版本叫Bazel(比如TensorFlow默认就用Bazel构建)。

Blaze2006年一路过来,也是各种经验啊:用BUILD替代Makefile,用Blaze替代Make,那么似乎应该让Blaze来解析BUILD然后调编译器连接器干活,因为Make就是先听Makefile哔哔然后向gcc和ar发号施令的。

但是既然已经是重新实现一个构建系统了,能不能把描述文件的语法搞的human friendly一点啊?干脆用Python写算了吧!

诶,如果BUILD用纯Python写,那Blaze就不需要解析BUILD了。但是!纯Python写/解析BUILD,太特么自由了,A君写一个宏,B君又写一个宏,实现同样功能。天啊,google那么多项目,这么搞搞死人啊。

好吧,捋一捋:

  • 构建的描述文件,语法得简单,或者说大家基本上熟悉的,门槛低点
  • 构建描述文件中常用的什么目标啊、库啊、路径啊、依赖啊,得有统一的版本
  • 构建速度得快点

其中对于前面两点,干脆搞个阉割版的Python(语言)吧!搞一些限定,但是python的常用基本语法给他留着。

好了,这就是Starlark了。对,它改过名,以前叫Skylark。

Starlark设计需求

Starlark除了是一门Python方言,它更是Blaze(Bazel)的前端。要想Bazel构建速度快,应该避免重复计算,Starlark作为预处理器,这么干的:

  • 搞了一个依赖图(graph of dependencies),这么一来不管你在BUILD.bzl文件中怎么瞎importimport的顺序不会影响构建速度
  • 根据这个图呢,先算“叶子节点”,也就是不依赖任何东西的任务,然后把依赖叶子节点的任务做做掉。好吧,这就是图的搜索算法,主要标记visit flag来避免重复计算。
  • 每个文件只被加载一次:缓存着,避免I/O阻塞计算速度
  • 考虑到多个BUILD文件中可能使用了同一个变量,多线程解析各个BUILD文件时给变量加只读锁
posted @ 2019-01-18 17:25  ChrisZZ  阅读(5529)  评论(2编辑  收藏  举报