大部分人都至少接触过不止一种构建工具,比如make,autotools。而我们开发了Blade,为什么那么多现成的工具不用,而又再造了一个轮子,相对于传统的make等工具,Blade的好处在又哪里呢?你的项目是否适合用Blade来构建,

以前的文档都是冷冰的介绍,今天本文将从作者和开发人员以及项目代码维护者的角度回答这些问题。

Blade总的来说要解决这些问题:

真正环境下的C++软件的开发,往往有数十人甚至数百个开发人员,源代码有成千上万个文件,百万甚至千万行。如何高效而安全地构建这些代码?

为了保证代码质量,我们还需要Codereview,代码提交流程,自动检测工具,单元测试,持续集成等现代化的开发流程,如何保证这些流程被实施?
Blade就是为这样的项目而生的。

下面是我分析的Blade的特点:

[构建规则简单]
Blade的构建规则很简单,是说明性而非指令性的,只要描述出源文件以及依赖即可,不需要描述如何构建。我比较过gyp和cmake的构建规则,都不如blade的简洁。

因为描述的是需要什么而不是怎么做,因此不需要开发人员掌握gcc的命令行,更无需记忆make的哪些奇奇怪怪的自动变量,大幅度降低使用门槛。

Blade还直接支持编译 protobuf,lex, yacc, swig 等,不需要自己写构建命令和规则。

[自动依赖分析和传递]
用过Make的都知道,所有的依赖关系要自己维护。我们都知道C/C++语言中的头文件是个很麻烦的事情,
在手工维护的make的依赖规则中,一般只写出.o文件对.c文件的依赖,这样当.c文件所包含的头文件变化时,
不会自动构建,这时候往往是需要做一次make clean然后重新编译,用make维护增量构建的意义大减。
即使写了对头文件的依赖,但是头文件里还会包含头文件,对于这些间接包含的头文件,是多到无法写出的。

而Blade自动分析头文件依赖关系,构建受影响的代码。头文件变化时,所有直接和间接包含它的源文件都会
被自动找出来,进行构建。而不受影响的源文件则无需重复构建,真正实现了增量构建。对于链接也是一样。

对于大的项目,我们往往分成多个库来构建,而且库之间还会有依赖关系,如果用了一个库,在用make的时候,
我们需要在命令行把它依赖的库都列出来,一个都不能少,而且顺序还不能错,否则都会导致链接错误。
更麻烦的是,假如某个库的实现变了,不再增加了一个新的依赖,那么所以用到这个库的地方都需要修改加上这个依赖。
Blade只需要开发人员写出直接依赖,而库的间接依赖是自动分析出来的,构建时也会自动检查所依赖的库是否需要重新构建。

[提高代码可读性]

既然Blade的构建理念是把整个项目看作一个有机的整体,那么头文件和库文件都在这个项目中有唯一的位置,天然不会重复,不怕重名。我多次经历或者见过头文件或者库文件重名,每次都浪费大量的时间。

Blade提倡从项目根目录开始定位文件和库,彻底避免了这样的问题。在这样方式组织代码的项目工作越久,就越能体会到Blade提倡的#include 从根开始写是在保护你而不是在故意为难你,并开始喜欢这种组织方式。

[构建速度优化]
除了上面所说的依赖关系维护消除了clean使得只需要增量构建外,Blade还开启了并行构建,默认多个进程同时构建,提高构建速度。
对于make也不是不可以并行构建,但是由于依赖关系的负责性,更容易出错。
为了进一步提高构建速度,Blade还支持ccache缓存构建结果和distcc分布式构建。

[易用性]
持续集成是代码质量的有效保证。通过持续集成,使代码持续处于可构建状态,大幅度减少了错误,提高了发布和部署的效率。
在做发布和持续集成时,我们常需要一次构建所有的目标,有时候还需要涉及32位64位等多个平台。
用make时一般的做法是用递归make,在上层的makefile里描述出有哪些子目录,并层层递归。这样的缺点是,
底层目录改动需要修改上层的Makefile,再加上库的依赖不能传递,使得makefile维护的大项目经常处于无法完整成功构建的状态。

Blade支持一下子构建整个目录树,并不需要写额外的描述。

对于递归make,两个目录有依赖关系时,依赖者就无法单独构建,需要跑到上层目录,先构建依赖,再构建自己才行。否则可能会用到旧的库。
Blade在代码树的任意子目录下都能构建,其依赖会被自动找出来构建,不多不少,确保正确性。

Blade内置 debug/release 两种构建类型,32/64位两种目标平台。

Blade的构建进度显示被大幅度简化为做了什么而不是在怎么做,减少了make中默认显示出的完整命令行对视觉的干扰。
为了更醒目地发现问题,构建过程中的警告和错误信息是用彩色高亮现实的,一眼就能看到错误提示行。

Blade的命令行接口类似svn,由一系列子命令,目标名和参数组成,简单好记忆,还支持bash风格的命令行补全,按tab键自动补全命令行。

[方便部署]

在我看来动态库就是灾难,见过不少依赖dlopen加载的库/框架,有的还支持热卸载,甚至想在同一个进程中加载不同版本的两个库来做对比测试,这样的项目无不bug不断,开发人员痛苦不堪。

因此Blade提倡静态链接,默认甚至把libstdc++和libgcc都静态链接到了可执行文件。发布时一个可执行文件就搞定(可能还需要一些配置文件,数据文件等)。省时省心。

[测试支持]
单元测试是代码质量的重要保证,可以把大量的低级错误消灭在萌芽状态,并提高代码的可维护性,降低开发成本。
用make的时候,一般是写一些可执行文件类型的目标,构建出来后,在人工运行它,没有任何机制保证这些测试会被运行。
如果测试写了不运行就等于白写,Blade直接支持类型为测试的目标类型,只需要描述哪些目标是是测试即可。Blade支持命令行批量执行这些测试。
因此运行测试可以由开发人员主动进行,也可以通过开发流程工具,在代码发起review或者提交前运行,以及持续集成时运行,使得测试真正做起来。
为了提高测试效率,自动支持多个测试进程并发运行,支持增量测试(自动跳过最后一次是成功且没有新的变化的测试程序)。
为了检查内存泄露,测试集成 gperftools,自动检测测试程序的内存泄露,使得大部分内存泄露可以在单元测试时发现。

最后总结一下,Blade是为了减轻大规模C++项目的维护成本,提高开发效率和质量而生的现代化构建工具。

Blade和其他构建工具有什么不同的更多相关文章

  1. Google软件构建工具Bazel原理及使用方法介绍

    近期,Google开源了强大的自动化构建工具Bazel. 正好博主近期在使用china版的Bazel--腾讯自主开发的Blade,所以准备跟大家分享一下Google Bazel这个分布式构建系统的原理 ...

  2. Gulp:自动化构建工具

    一.介绍: gulp是一个基于流的构建工具,可以自动执行指定的任务,简洁且高效 二.优点: 开发环境下,想要能够按模块组织代码,监听实时变化 css/js预编译,postcss等方案,浏览器前缀自动补 ...

  3. 前端构建工具之gulp(一)「图片压缩」

    前端构建工具之gulp(一)「图片压缩」 已经很久没有写过博客了,现下终于事情少了,开始写博吧 今天网站要做一些优化:图片压缩,资源合并等 以前一直使用百度的FIS工具,但是FIS还没有提供图片压缩的 ...

  4. 前端构建工具之gulp_常用插件

    gulp常用插件的使用 今天来看看一下gulp的常用插件的使用 就像gruntjs需要一个Gruntfile.js文件一样,gulp也需要一个文件作为它的主文件,在gulp中这个文件叫做gulpfil ...

  5. 前端构建工具的用法—grunt、gulp、browserify、webpack

    随着前端项目的飞速发展,项目越来越大.文件越来越多,前端工程化的工具也越来越多.下面介绍目前最流行的四种构建工具——grunt.gulp.browserify.webpack 所有的构建工具都是基于N ...

  6. Google软件构建工具Bazel FAQ

    Google软件构建工具Bazel FAQ 本文是我的翻译,原文在这里.欢迎转载,转载请注名本文作者和原始链接 注:如果想了解Bazel的原理,可以看看我之前翻译的Google Blaze原理及使用方 ...

  7. 为什么google bazel构建工具流行不起来

    作者Jack47 转载请保留作者和原文出处 之前博主写了系列文章Google软件构建工具Bazel原理及使用方法介绍.最近使用了一段时间后,觉得这个东西不是一种通用的构建工具,很难对接到情况复杂的大的 ...

  8. 前端构建工具gulpjs的使用介绍及技巧

    gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学习起来很容易,而且gulpjs使用的是nodejs中stream来读取和操作数据,其速 ...

  9. gulp自动化构建工具

    gulp    自动化构建工具,实时监控.代码合并.压缩... http://www.gulpjs.com.cn/     中文网 http://gulpjs.com/plugins/     英文网 ...

随机推荐

  1. 理解线程的挂起,sleep还有阻塞

    线程是靠cpu来运行的,cpu要运行一个线程(不说别的)最起码就是要占用cpu时间,象Windows这样的多任务操作系统,可以允许多个线程同时运行,所谓的同时运行并不是真正的同时运行,而是轮流运行不同 ...

  2. C#防SQL注入代码的实现方法

    对于网站的安全性,是每个网站开发者和运营者最关心的问题.网站一旦出现漏洞,那势必将造成很大的损失.为了提高网站的安全性,首先网站要防注入,最重要的是服务器的安全设施要做到位. 下面说下网站防注入的几点 ...

  3. 表单数据校检方法 onsubmit()的使用?

    在项目中为一个表单(from)编写onsubmit()脚本的时候,经常需要验证表单中数据的合法性 所以常会写道:<form action="/admin/addUser.do" ...

  4. Unity扩展编辑器--类型1:Editor Windows

    Extending the Editor Unity允许你使用自己定制的inspectors和Editor Windows扩展编辑器,并且你可以使用定制的Property Drawers定义属性集在i ...

  5. iOS开发:使用Block在两个界面之间传值(Block高级用法:Block传值)

    iOS开发:使用Block在两个界面之间传值(Block高级用法:Block传值)   使用Block的地方很多,其中传值只是其中的一小部分,下面介绍Block在两个界面之间的传值: 先说一下思想: ...

  6. Solr4.8.0源码分析(15) 之 SolrCloud索引深入(2)

    Solr4.8.0源码分析(15) 之 SolrCloud索引深入(2) 上一节主要介绍了SolrCloud分布式索引的整体流程图以及索引链的实现,那么本节开始将分别介绍三个索引过程即LogUpdat ...

  7. C语言学习笔记--枚举&结构体

    枚举 枚举是一种用户定义的数据类型,它用关键字enum以如下语法格式来声明: enum 枚举类型名字 {名字0,名字1,...,名字n}: 枚举类型名字通常并不真的使用,要用的是大括号里面的名字,因为 ...

  8. 极简易版专家聊天程序--JAVA练手

    呵呵,用JAVA包开发SOCKET连接,是很简单的呢~~~ DailyAdviceServer.java import java.io.*; import java.net.*; public cla ...

  9. 【HDOJ】1561 The more, The Better

    树状DP. /* 1561 */ #include <iostream> #include <cstdio> #include <cstring> #include ...

  10. COJN 0575 800601滑雪

    800601滑雪 难度级别:B: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是 ...