scons 是一个 Python 写的自动化构建工具,从构建这个角度说,它跟 GNU make 是同一类的工具。它是一种改进,并跨平台的 gnu make 替代工具,其集成功能类似于 autoconf/automake 。scons 是一个更简便,更可靠,更高效的编译软件。
From Wikipedia, the free encyclopedia
SCons is a computer software construction tool that automatically analyzes source code file dependencies and operating system adaptation requirements from a software project description and generates final binary executables for installation on the target operating system platform. Its function is analogous to the traditional GNU build system based on the make utility and the autoconf tools.
Scons uses the Python general purpose programming language as a foundation, so that all software project configurations and build process implementations are Python scripts.
Major features
* Configuration files are Python scripts, which means that user-written builds have access to a complete general-purpose programming language. * Automatic dependency analysis built-in for C, C++ and Fortran. Dependency analysis is extensible through user-defined dependency scanners for other languages or file types. Unlike the GNU Compiler Collection's (GCC) built in dependency analysis, it uses a regular expression scan for included source files. * Built-in support for the C, C++, D, Java, Fortran, Objective-C, Yacc, Lex, Qt and SWIG, and building TeX and LaTeX documents. Other languages or file types can be supported through user-defined Builders. * Building from central repositories of source code and pre-built targets. * Built-in support for fetching source files from revision control systems, such as SCCS, RCS, CVS, Subversion, BitKeeper and Perforce. * Built-in support for Microsoft Visual Studio, including generation of .dsp, .dsw, .sln and .vcproj files. * Detection of file content changes using MD5 signatures; optional, configurable support for traditional timestamps. * Support for parallel builds which maintains a specified number of jobs running simultaneously regardless of directory hierarchy. * Integrated Autoconf-like support for finding #include files, libraries, functions and typedefs. * Global view of all dependencies, so multiple build passes or reordering targets is not required. * Ability to share built files in a cache to speed up multiple builds - like ccache but for any type of target file, not just C/C++ compilation. * Designed from the ground up for cross-platform builds, and known to work on POSIX systems (including Linux, AIX, *BSD systems, HP-UX, IRIX and Solaris), Windows NT, Mac OS X, and OS/2.
History and related projects
SCons software history started with the Cons software construction utility created by Bob Sidebotham in 1999[1]. Cons was written in the Perl programming language. It served as a base for the ScCons build tool, a design which won the Software Carpentry project SC Build competition in August 2000.[citation needed] ScCons was the foundation for Scons.
SCons inspired the creation of Waf, formerly known as SCons/BKsys, which emerged in the KDE community. For some time, there were plans to use it as the build tool for KDE 4 and beyond, but that effort was abandoned in favor of CMake.[2] Notable applications using Scons
* Ardour * Battlefield 1942 * Blender * Csound * Google Chrome[3] * GtkRadiant[4] * M5 * Nullsoft Scriptable Install System * NumPy and SciPy * SuperCollider * VMware * XORP * MCA2[5]
References
External links Free software portal
* SCons Home Page * Make Alternatives * Empirical Comparison of SCons and GNU Make, Ludwig Hähne, Technical University Dresden, August 21, 2008
原文:http://www.go4pro.org/?p=47
29 Oct 08 scons 简介 by 令狐虫
云风在 blog 上写了一组《IDE 不是程序员的唯一选择》的文章。题目很吸引人,以至于我一直以为他要写什么鸿篇巨制,可惜到最后只出现了一组《GNU make 入门指南》。(笑)
被 IDE 绑定的确是一件很悲哀的事情。作为一个程序员,当然应该搞清楚程序编译链接的整个流程,makefile 给出了很好的一个路径,让我们能够了解这一点。
但是,如果觉得程序员就应该比拼"手写汇编代码"、"用记事本写程序",那就大大的错了。程序员需要了解细节,但不意味着程序员都是傻瓜。为什么要放着好好的提高生产力的工具不用,一切从零做起呢?(当然了,上面这句话并不能成为使用盗版的理由。)所以寻找并了解一些优秀的工具,也是我们这些程序员所需要做的事情之一。
GNU make 当然是一个很好的工具,云风已经讲了很多,我就不啰嗦了。我今天想介绍另一个优秀的自动构建工具 scons。
scons 是一个 Python 写的自动化构建工具,从构建这个角度说,它跟 GNU make 是同一类的工具。它有什么好处呢?在它自己的网站上,当然写了一大堆了,快速、稳定、强大、跨平台、可扩展??。不过我们还是从自己的角度来看看它到底好在哪里。
刚刚提到 scons 从目的而言跟 GNU make 是同一类的工具。但是实际上,它的思想是跟 GNU make 完全不同的。GNU make 的核心是?依赖关系?,我要做的事情,就是告诉系统,一个目标依赖什么东西,并且,当被依赖的东西发生变化时,我要做什么。这样做可以解决相当多的问题,但是也带来了一个最大的问题:我如何判别这个目标依赖什么?
对于一个两个,甚至十几个文件,我当然还比较容易搞清楚,谁依赖谁。但是当文件有成百上千个时,要分清楚谁依赖谁可就没这么容易了。尤其是 C/C++ 头文件的依赖,如果手工分析的话,工程量可是不小。为了解决这个问题,GNU 又提供了另外一套工具:Automake,使用程序来分析依赖性,然后辅助你产生 makefile。
于是乎,就有人想了,既然如此,我干吗费那劲,用程序分析依赖性,然后生成一个文件,再交给另外一个程序去处理呢?既然依赖性需要用程序来分析,那么就直接交给构建工具本身去做不就好了吗?对的,这是一个非常自然的思路,于是,Java 世界有了 Ant,而 Python 世界有了 scons。
scons 就是这样一个构建工具:你告诉它要做的任务,以及完成这个任务需要的输入,以及这个任务产生的输出,怎么做这个任务(当然其中就包括依赖性分析),就交给工具本身完成。
说了这么多,我们来看看一个现实世界的 scons 是什么样子的。
我们假设有一个 C 程序,由三个文件组成:
//-----func.cpp int add(int x, int y) { return x+y; }
//----func.h #ifndef FUNC_H #define FUNC_H extern int add(int x, int y); #endif
//-----main.cpp #include #include "func.h"
int main() { printf("2+3=%d\n", add(2, 3)); }
然后我们写一个 SConstruct 文件(类似于 GNU make 的 Makefile 文件,是 scons 的默认文件名):
Program('add_main', ['main.cpp', 'func.cpp'])
然后执行 scons,将会输出以下信息:
scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... g++ -o main.o -c main.cpp g++ -o func.o -c func.cpp g++ -o add_main main.o func.o scons: done building targets.
这时,我们就会得到一个 add_main 的可执行程序。
如果执行 scons -c,我们会看到:
scons: Reading SConscript files ... scons: done reading SConscript files. scons: Cleaning targets ... Removed main.o Removed func.o Removed add_main scons: done cleaning targets.
生成的可执行程序连带中间结果都被清除了。
这里我们可以看到,scons 只需要描述任务,并不需要指定依赖关系,甚至我们都没有指出头文件,但是你修改 func.h 的时候仍然会触发构建。这是因为 scons 内部有个 scanner,可以帮助扫描包含文件的关系。(我们可以编写自己的构建任务,当然也可以编写自己的 scanner,有兴趣的可以看帮助,这里就多说了)
我们还发现,这里我们根本没有指定编译器,也没有指定编译选项,但 scons 仍然很聪明的选择了 g++(这是 Linux 上的结果,如果是 Windows,默认会选择 cl 也就是 Visual C++),并且给出了正确的编译选项。事实上,这是因为 scons 内置提供了很多编译器及其对应选项的选择,然后对于不同的平台,会有一个默认项。我们当然也可以自己选择编译环境,比如在 Windows 下,我同时安装了 VC 和 mingW,但是我想用 mingW 来编译而不是 VC,就可以这样指定:
import os env = Environment(ENV=os.environ, tools=['mingw']) env.Program('add_main', ['main.cpp', 'func.cpp'])
这里出现了一个 Environment 的概念,Environment 可以设置编译的环境。这是一个简介,所以对于它我们就不多说了,感兴趣的可以自行查阅资料。嘿嘿。
在这里我们看到了一句熟悉的语句:import os。是的,SConstruct 文件就是一个非常标准的 Python 程序,所以,Python 能做什么,scons 就能做什么。很好很强大阿,哈哈。(这里顺便说一句,我们也可以认为 Makefile 是 shell 程序,但是因为 shell 有平台相关性问题,我们很难写出一个通用平台的 Makefile,但是我们还是写的出一个通用平台的 SConstruct 的。)
Program 只是 scons 支持的构建任务其中的一种,用于根据后缀名自动构建 C、C++、D 和 Fortran 的可执行程序。scons 还支持另外几十种构建目标,这里可以查看支持的列表。如果这里找不到的,还可以自己编写 Builder 和 Scanner。
接下来我想给出一个一直提但是一直没有给出结果的东西,就是对 C++ 程序的单元测试。
还是以刚刚那个小例子为例。我们对 add 函数作一个单元测试。我们知道,单元测试不是程序的一部分,所以需要一个独立的 main 函数。而被测试的单元是一样的。
现在假设我们有一个测试函数:(用的是 boost 的 test 库,这个库的使用方法不再赘述)
//--------test_main.cpp #include "func.h" #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MAIN #include
BOOST_AUTO_TEST_CASE( add_test ) { BOOST_CHECK( add(2, 2) == 4 ); }
然后我们写一个 SConstruct:
# 所有的需要测试的单元文件(去除两个主文件) import glob obj_files = glob.glob('*.cpp') obj_files.remove('main.cpp') obj_files.remove('test_main.cpp')
common = Object(obj_files)
Program('add_main', ['main.cpp'] + common) Program('unittest', ['test_main.cpp'] + common, LIBPATH='/usr/lib', LIBS=['libboost_unit_test_framework'] )
Alias('test', 'unittest') Default('add_main')
这里出现了几个新玩意儿,一个是 Object,其实也很好理解,Object 就是将指定的文件编译成目标文件(.o 或者.obj),然后我们用了 2 个 Program,表示要生成两个可执行文件。在生成的时候,我们将通用的 common 附加到构建输入中。另一个是 Default,这是表示默认的构建。当我们输入 scons 时,将构建 add_main,而我们输入 scons unittest 时,则构建 unittest。但是输入 unittest 感觉不太方便,我们想输入 scons test 来编译,但希望输出的文件名仍然是 unittest,于是我们增加了 Alias,将 unittest 取了一个别名叫 test,这时,我们输入 scons test,仍然会构建 unittest。
我们注意到构建 unittest 时,使用了附加的信息,比如额外的库、额外的路径等等。还有为了方便起见,我们使用了 Python 标准库的 glob 函数展开文件通配符。
从这个例子我们大约可以感受到 scons 的强大威力了。至于进一步的深入,就看各位自己的了。
-- 陈寅恪:"中国人之哲学美术,远不如希腊,不特科学为逊泰西也。但中国古人,素擅长政治及实践伦理学,与罗马人最相似。其言道德惟重实用,不究虚理。其长处短处均在此。长处即修齐治平之旨,短处即实事利害得失观察过明,而乏精深远大之思。故昔则士子群习八股以得功名富贵,而学德之士终属极少数。今则凡留学生皆学工程实业,其希慕富贵不肯用力学问之意则一,而不知实业以科学为根本,不揣其本而治其末,究其极只成下等之工匠。境遇学理,略有变迁,则其技不能复用。所谓实学者,乃适成为最不实用。至若天理人事之学精深博奥者,亘万古横九垓而不变,凡事凡地均可用之。而救国经世,尤必以精神之学问(谓形而上之学)为根基。乃吾国留学生不知研究,且鄙弃之。不自伤其愚陋,皆由偏重实用积习未改之故。此后若中国之实业发达,生计优裕,财源浚辟,则中国人经商营业之长技,可得其用,而中国人当可为世界之富商。然若冀中国人以学问美术等之造诣胜人,则决难也。"
1919年12月14日吴宓《雨僧日记》