Scons工具简介:
Scons是一个类似于make的构建工具,通过定义Scons描述文件(Sconstruct),即可实现类似于make命令的本地编译功能。
方法:
- 基本框架是先绘制图,这里的绘制图是分散在不同目录下的不同文件中的(Sconstruct文件,和Makefile文件类似的作用);
- Sconstruct文件内部可建立对于其他节点、lib的依赖;
- Scons读取每个目录下定义的脚本文件,收集到所有的node之后,再统一生成一棵依赖关系树。数据结构采用的是children的子集模式,每个node维护各自子集的指针;
- 对于编译这样其实还不够,因为编译本身有包含.h等一些隐藏的依赖,Scons的做法是定义一个通用接口(scanner),针对不同的编译器命令,配置不同的scanner,来实现分析隐藏依赖的目的。可以自己实现scanner。Scons本身提供的是使用正则表达式来分析隐式依赖的方法。有一些小问题(无法展开宏定义,无法区分注释内部的include等)。如果有其他工具,Scons还支持调用其他工具来分析隐藏的依赖。这样一来,对于编译来说,就完整了,Scons内部就会有一套完整的依赖关系,形成一个有向无环图;
- 编译过程就变成了一个dag调度的过程。(当然,这里还有一些编译命令、环境变量、编译参数的问题,这些其实都是小问题,Scons的脚本中提供了很多的api,调用并设置一下就行了);
- 最后,可能还有一些nice to have的特性,比如增量编译、清理、除了编译之外的特殊命令的支持等等(因为Scons本质上的功能是通过用户的定义,能够在python中生成一棵依赖关系树,其实起的是这个关系建立的作用(当然,他也支持对于这颗树的dag调度),所以理论上,每个节点可以执行任意的命令,(编译、拷贝,执行python脚本、甚至可以调用一个python函数),Scons只是负责说先执行哪个,后执行哪个的功能而已(类似于一套逻辑模型+执行模型的组合,可以填充任意的数据进去的);
说明:
- Scons是python编写的,继承了python语言的特性,优点是直观、灵活、易用、易于维护,Scons还自带生成dag的能力,这对于分布式编译是非常重要的一个能力,这是makefile所不具备的;
- Scons的缺点也比较明显,相比较于cmake等c编写的工具,性能上差距比较明显,因此对于一些小型项目,更加适用;
- 由于Scons的性能损耗主要在checksum的计算以及隐式依赖的分析,同时Scons又支持调用任意的工具,因此通过c语言来实现隐式依赖的并行分析以及checksum的计算,可以大幅度提升Scons的性能,弥补Scons的缺陷;
- 总之,Scons的灵活性注定了其是一个具有很大的潜力的构建工具,适当的改造后,完全具备支持大型项目编译的能力,丝毫不逊色于makefile等传统的构建工具;
- 如需了解更多Scons相关内容,请参考Scons GitHub开源项目