Blade

typhoon-blade

Blade is an advanced building system developed with python, majorly for C/C++

Blade 是一个现代构建系统,期望的目标是强大而好用,把程序猿从构建的繁琐中解放出来。

Blade主要定位于linux下的大型C++项目,密切配合研发流程。比方单元測试。持续集成,覆盖率统计等。但像unix下的文本过滤程序一样,保持相对的独立性,能够单独执行。眼下重点支持i386/x86_64 Linux,未来能够考虑支持其他的类unix系统。

在腾讯公司“台风”云计算平台开发过程中。为了解决 GNU Make,Autotools 的难用和繁琐的问题,我们开发了这个全新的构建系统。整个系统基于多个声明式的构建脚本,在构建脚本里,仅仅须要声明要构建什么目标,目标的源码,以及其直接依赖的其他目标。不须要说明怎样构建。大大降低了使用难度。提高了开发效率。

首先。Blade攻克了依赖问题。 当你在构建某些目标时,头文件有变化,会自己主动又一次构建。 最方便的是,Blade也能追踪库文件的依赖关系。比方 库 foo 依赖库 common,那么在库 foo 的 BUILD 文件里列入依赖:

  1. cc_library(
  2.     name = 'foo',
  3.     srcs = ...
  4.     deps = ':common'
  5. )
复制代码
那么对于使用foo的程序,假设没有直接用到common。那么久仅仅须要列出foo。并不须要列出common。

  1. cc_binary(
  2.     name = 'my_app',
  3.     srcs = ...
  4.     deps = ':foo'
  5. )
复制代码
这样当你的库实现发生变化。添加或者降低库时,并不须要通知库的用户一起改动,Blade自己主动维护这层间接的依赖关系。当构建my_app时,也会自己主动检查foo和common是否也须要更新。

说道易用性。除了依赖关系的自己主动维护。Blade还能够做到。仅仅要一行命令。就能把整个文件夹树的编译连接单元測试就能够全部搞定。

比如:

递归构建和測试common文件夹下全部的目标

  1. $ blade test common...
复制代码
以32位模式构建和測试
  1. $ blade test -m32 common...
复制代码
以调试模式构建和測试
  1. $ blade test -pdebug common...
复制代码
显然。你能够组合这些标志
  1. $ blade test -m32 -pdebug common...
复制代码
特点

          自己主动分析头文件依赖关系。构建受影响的代码。
          增量编译和链接,仅仅构建因变更受影响而须要构建的。
          自己主动计算库的间接依赖。库的作者仅仅须要写出直接依赖,构建时自己主动检查所依赖的库是否须要又一次构建。
          在随意代码树的随意子文件夹下都能构建。
          支持一次递归构建多个文件夹下的全部目标。也支持仅仅构建随意的特定的目标。
          不管构建什么目标,这些目标所依赖的目标也会被自己主动连坐更新。
          内置 debug/release 两种构建类型。


          彩色高亮构建过程中的错误信息。
          支持 ccache
          支持 distcc
          支持基于构建多平台目标
          支持构建时选择编译器(不同版本号的gcc。clang等)
          支持编译 protobuf,lex, yacc, swig
          支持自己定义规则
          支持測试,在命令行跑多个測试
          支持并行測试(多个測试进程并发执行)
          支持增量測试(无需又一次执行的測试程序自己主动跳过)
          集成 gperftools,自己主动检測測试程序的内存泄露
          构建脚本 vim 语法高亮
          svn 式的子命令命令行接口。
          支持 bash 命令行补全
          用 Python 编写,无需编译,直接安装使用。



彻底避免以下问题:


    头文件更新,受影响的模块没有又一次构建。
    被依赖的库须要更新。而构建时没有被更新,比方某子文件夹依赖遥远的某外部文件夹的代码,我在这个文件夹构建,外部文件夹的代码会被自己主动检查是否也须要又一次构建。

致谢
Blade 是受 Google 官方博客发表的这篇文章的思想的启示而开发的: 云构建:构建系统是怎样工作的

现阶段 Blade 生成 SCons 脚本进行构建。因此 Blade 的执行还须要依赖 SCons。

Python 是一种简单易用而又强大的语言。我们喜欢 Python。

Google 开放的一些库强大而好用。我们非常喜欢,我们把对这些库的支持集成进了Blade中。既方便了库的使用,又增强了 Blade,这些库包含 protobuf,gtest, gproftools。



很多其他文档请參考 Wiki。

欢迎使用以及帮助我们改进Blade。我们期待你的贡献。

GAE 地址:http://code.google.com/p/typhoon-blade/

GitHub 地址:https://github.com/chen3feng/typhoon-blade




刀是什么样的刀?

诸位看到标题。千万不要以为我是模仿《瑞丽的JQuery》。或者什么书籍,而是由于,介绍Blade的文章,标题不得不这样。

Blade由腾讯台风云计算平台出品。大约在2012年下半年开源。它是一把专用于构建软件的宝刀。

Blade的字面意义应该是"刀锋",意思是使用该软件构建软件更加强大,更加便捷。该系列宝刀,最早应该是由Google这位顶级刀匠打造而成,当年事迹见诸互联网记载:

http://google-engtools.blogspot.hk/2011/08/build-in-cloud-how-build-system-works.html

http://mike-bland.com/2012/10/01/tools.html#tools-blaze-forge-srcfs-objfs

 

听说Google内部打磨的宝刀。其名为"火焰刀",英文名为"Blaze",一样是锋芒毕露,炙热灼物,其面世后,以其熊熊烈焰。统一了google内部的软件编译方式。

腾讯出品的blade, 英文写法,仅仅有一字之差。只是"火焰""刀锋"各得风流,虽说取名有点像偶像致敬的意思,可是也是锋芒不让。

 

提起google的宝刀。事实上到google洗练过几年武学的IT牛人们,在远走他方后。也都各自打磨了一把。我的前东家。就成绩打磨过一把相似的宝剑,取名"Ymake",名字是尽管朴拙了一些,可是假如你见过他们亮出过宝刀。也会被其锋芒所吸引。在云壤的江湖朋友们。都称道其"活儿好"。

 

就互联网上能搜索到的铸刀秘诀而言,我能搜索到的,应该是我的前任授业恩师放出去的,事实上他应该还没有添加云壤。项目地址为:

https://code.google.com/p/qa52/

其BUILD语法,尽管还没有简洁到极致。可是功能上似乎看起来也已经有模有样。

 

其演示样例的BUILD文件例如以下所看到的:

假如你细致瞅瞅,会发现语法已经基本接近google开放出来的BUILD文件演示样例。

 

好吧。花了九牛二虎之力,追溯了blade的历史掌故,却还没点到题上。

言归正传,blade事实上是一个多语言的构建工具,之所以使用"构建"。而不是"编译"两字,实在是由于软件构建并不仅仅是软件编译。而非我喜欢故弄玄虚。

Blade除了编译软件以外,还奉上了非常多其他的福利。比方集成了单元測试,性能測试等。这正如一把好刀,不仅应该能杀人,还且最好能力最短的时间内杀死对方。刀光一起。人已倒地,可是刀不流血,刀已回鞘。

 

那么,Blade藏身何处,不急。以下就是它的所在:

https://code.google.com/p/typhoon-blade/

https://github.com/chen3feng/typhoon-blade

眼下该项目与陈峰维护。其微博名为"陈三丰",尽管我推測可能是由于"陈峰"这个名字已经被他人抢先使用,继而仅仅好採用拆字法,将"峰"一分为二,是为"三丰"。只是从名字看。倒也和大侠张三丰非常有渊源,就此而言,blade(刀锋)由他维护倒是最妙只是了。

刀锋的锋芒在哪里?

 

既然号称刀锋,那么其锋芒何在?为什么有了make这把天下闻名的好刀,还要试试blade的锋芒?

那么以下就在历数一下blade的不同凡响处。

天下武功。唯快不破

 

江湖上最知名的刀,无不以快而闻名。blade的一个优点。也是其编译速度快。快得益于几个方面:

1,能够进行并行编译和并行測试。

2,使用了ccache等库,能够将编译中间结果进行缓存。

3,假设使用了distcc模式,则能够享有很多其他的用于编译的硬件资源。

听说google内部的blaze有三个模式,一个是Local,一个是distcc,一个是Forge,按理说。forge模式由于执行在大规模的集群中,编译的速度应该最为快。

刀虽为刀,却不仅仅是刀

 

在仙剑奇侠传四中,宝剑望舒,被男主角云天河各种虐待,从猎野猪、烤肉、劈柴到射箭、御剑,无所不用其极。而一把好刀,其功能自然不应该局限与杀人见血。

Blade作为一个构建工具,其作用不仅仅是替代makemakefile,且听我细细道来:

1Blade是软件project的利器。有助于模块化,模块化的力度控制自如。对于提高系统的可维护性。复杂性的隔离。代码复用的最大化。都有非常大的优点。

2Blade提供了单元測试的最佳使用方式。

假若单元測试和代码是分离的,编译代码和执行測试各自为政,那么往往測试仅仅是測试,非常难对开发有什么帮助,由于非常多时候,尽管有測试代码,可是測试却非常少被执行,或者时过境迁后,測试多有失效。

大家假如编译过一些开源项目的话,可能就会有相似的经验。编译完静态库。拿到静态库文件就完了,非常少有人去执行全部的单元測试,确保全部的測试都能执行通过。

有了Blade,通过cc_testgtest_main.a默认链接,使得单元測试的代码简化到极致。同一时候,主要执行blade test target,就能在编译完目标程序后。执行(并且可并发执行)对应的单元測试,以随时跟进代码是否已经偏离了该有的轨道。开发是否早已脱缰狂奔。

仅仅要公布部署时,使用上Blade test target, 那么就能够保证。上线的模块,能够通过全部单元測试用例的验证把关。Blade集成单元測试。提供cc_test,看似功能简单,可是正是这个简单的功能,使得測试驱动开发。开发人员測试等理念。能够在google全功能范围内得到认同并贯彻实现。

3blade实现了递归编译。

Blade build …就可以对当前文件夹及其子文件夹下的全部编译对象进行编译。

该功能尽管小,可是却非常有用。

在一个十几人的团队中,百万行级别的代码规模。仅仅有递归编译功能。能够非常方便地实现一个循环编译工具。当某个模块编译失败。或者某个单元測试失败后,自己主动发出邮件通知相关的开发人员。以保证频繁的开发提交代码成为开发。当然,相关的功能。能够通过相似hudson之类的软件完毕。

只是blade 递归编译。对中小规模的代码而言,基本已经游刃有余。

4blade 实现了依赖查询。

Blade query能够查询依赖到某个模块的全部模块,这个对于代码重构而言,是个不错的功能。

假如你在重构code base,或者是改动接口。或者是fix bug,或者是改进性能,

都可能使得使用到该库的相关模块。集体罢工。单元測试无法通过。

这时候,假如使用上blade query,你就可能编译相关模块。使得你提交的代码,不会给其他模块带来麻烦。

5blade绑定了静态代码审查功能。

对整个项目而言。严把质量关非常重要,由于一旦一些烂代码进去了,清扫牛粪的工作将会非常痛苦并且艰巨。

这里的异己分子。可能包含bug,风格差异迥异等。

Blade 会在进行编译之前。会全部被变更的编码,使用指定的静态代码审查功能进行代码审查。

C++代码审查脚本。google cpplint较为知名,地址为:

http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py

当然,每一个公司都能够定制其自己的检查脚本,以符合其自己的代码风格等。

Blade绑定该功能,能够避免出现一些常见的Bug,统一团队的代码风格,对公司project文化的塑造有润物细无声之效。

6,blade是编译的统一入口。并且是开放的

这点是最重要的。也是blade的锋芒所在。由于Blade是统一的编译假设。因此改动统一的编译选项,设置统一的编译警告级别。实现cc_test等全部成为可能。

仅仅要愿意。你不仅能够在编译前实现代码审查。也能够在编译时设置不同的參数,选择指定的编译器。更能够在编译后,执行单元測试。统计单元測试覆盖率。当能够定制各种操作。

由于统一,所以要升级编译器。使用统一的警告级别等牵一发而动全身的动作成为可能。

由于开发,实现cc_test, cc_benchmark, proto_library, thrift_library成为可能。

 

好使的刀,方为好刀

假如刀尽管,可是太笨重。使用起来仿佛破解机关,这仅仅有寂寞的高手才干使用了。普通人得知,如同废铁。

因此,好使的刀,才是好刀。

Blade之所以好使,在于其採用了足够简洁的语法。比方以下便是编译一个静态库libencoding.a的语法描写叙述:

cc_library(

    name = 'encoding',

    srcs = [

        'ascii.cpp',

        'base64.cpp',

        'hex.cpp',

        'percent.cpp',

        'shell.cpp',

    ],

    deps = [

        '//toft/base/string:string',

        '//thirdparty/stringencoders:stringencoders'

    ]

)

你须要的仅仅有三件事。要打造的刀叫什么刀。它须要使用什么特别的原料。它须要依赖哪些现成的原料。也就是name, srcs,deps, 换言之,就是编译对象名。编译须要的源文件,须要依赖的其他静态库。

你须要描写叙述的有且仅有他们。

怎么编译,编译选项,在哪里编译,中间产物是什么,中间产物放在哪里。你通通不须要关注。

刀一出鞘,东西已在那,躺在了你希望它在的所在。热乎乎的,等你去品尝。

这样的简单到极致的语法,优点却有非常多。比方:

1, easy学习,easy记忆。你须要记忆的仅仅有name, srcs,deps等掰着十指都能数的过来的keyword和规则,剩下的就是。告诉它用到哪些代码文件,用到了哪些外部的库。

相比Makefile繁琐的语法。BUILD文件可谓清爽宜人。

2,简化到了极致的优点是,各种cc_library能够在力度中间轻松转换,因此使用了BUILD文件后,模块划分会更加合理,哪怕有一个文件,其他模块可能能够使用上。你也能够方便地将它打包到一个静态库中,这样其他地方仅仅要依赖上这个cc_library,就能够坐享其成。

我以前见识过各种thrift文件。protobuf文件散落在代码各个文件夹甚至分支中。假设使用上thrift_library, proto_library,将thrift文件定义出细粒度的library,则能够避免因Makefile中频繁描写叙述thrift/protobuf源文件生成与编译的痛苦。

羞于告诉他人的是。我至今都对Makefile不太熟悉,只是所幸,Blade已经开源,我从此不必也不像和Makefile再打交道,我也没有必要告诉别人说。我认识Makefile这个哥们。

宝刀待屠龙

江湖中向来有"武林至尊,宝刀屠龙,号令天下,莫敢不从,倚天不出,谁与争锋."的说法。blade既然是一把绝世好刀,在倚天剑面世之前,各位江湖好友,最好还是试试其刀锋怎样!


原文地址:https://www.cnblogs.com/zhchoutai/p/6952965.html