1、编译简单的C/C++程序
这是一个用C语言编写的著名的"Hello,World!"程序:
int main()
{
printf("Hello, World!\n");
}
用SCons编译它,需要在一个名为SConstruct的文件中输入如下命令:
Program('hello.c')
这个短小的配置文件给了SCons两条信息:你想编译什么(一个可执行程序),你编译的输入文件(hello.c)。Program是一个编译器方法(builder_method),一个Python调用告诉SCons,你想编译一个可执行程序。
现在运行scons命令编译这个程序。在Linux或Unix系统上,你会看到如下输出:
% scons
scons: Reading SConscript files...
scons: done reading SConscript files.
scons: Building targets...
cc -o hello.o -c hello.c
cc -o hello hello.o
scons: done building targets.
在一个带有微软Visual C++编译器的Windows系统上,你会看到如下输出:
scons: Reading SConscript files...
scons: done reading SConscript files.
scons: Building targets...
cl /Fohello.obj /c hello.c /nologo
link /nologo /OUT:hello.exe hello.obj
embedManifestExeCheck(target,source,env)
scons: done building targets.
首先,你仅仅需要指定源文件,SCons会正确地推断出目标文件和可执行文件的名字。
其次,同样的SConstruct文件,在Linux和Windows上都产生了正确的输出文件:在POSIX系统上是hello.o和hello,在Windows系统上是hello.obj和hello.exe。这是一个简单的例子,说明了SCons使得编写程序编译脚本变得很容易了。
2、编译目标程序
Program编译方法是SCons提供的许多编译方法中一个。另一个是Object编译方法,告诉SCons从指定的源文件编译出一个目标文件:
Object('hello.c')
现在运行scons命令编译,在POSIX系统里它仅仅编译出hello.o目标文件:
% scons
scons: Reading SConscript files...
scons: done reading SConscript files.
scons: Building targets...
cc -o hello.o -c hello.c
scons: done building targets.
在Windows系统里编译出hello.obj目标文件:
scons: Reading SConscript files...
scons: done reading SConscript files.
scons: Building targets...
cl /Fohello.obj /c hello.c /nologo
scons: done building targets.
3、简单的JAVA编译
SCons同样使得编译Java也很容易了。不像Program和Object两个编译方法,Java编译方法需要你指定一个目录,这个目录是用来存放编译后的class文件的,以及一个存放.java源文件的目录:
Java('classes', 'src')
如果src目录仅仅包含一个hello.java文件,那么运行scons命令的输出会如下所示(在POSIX系统里):
% scons
scons: Reading SConscript files...
scons: done reading SConscript files.
scons: Building targets...
javac -d classes -sourcepath src src/hello.java
scons: done building targets.
4、编译之后清除
使用SCons,编译之后想要清除不需要增加特殊的命令或目标名。你调用SCons的时候,使用-c或--clean选项,SCons就会删除合适的编译产生的文件。
% scons -c
5、SConstruct文件
如果你使用过Make编译系统,你应该可以推断出SConstruct文件就相当于Make系统中的Makefile。SCons读取SConstruct文件来控制程序的编译。
5.1、SConstruct文件是Python脚本
SConstruct文件实际上就是一个Python脚本。你可以在你的SConstruct文件中使用Python的注释:
# Arrange to build the "hello" program.
Program('hello.c') #"hello.c" is the source file.
5.2、SCons的函数是顺序无关的
重要的一点是SConstruct文件并不完全像一个正常的Python脚本那样工作,其工作方式更像一个Makefile,那就是在SConstruct文件中SCons函数被调用的顺序并不影响SCons你实际想编译程序和目标文件的顺序。换句话说,当你调用Program方法,你并不是告诉SCons在调用这个方法的同时马上就编译这个程序,而是告诉SCons你想编译这个程序,例如,一个程序由一个hello.c文件编译而来,这是由SCons决定在必要的时候编译这个程序的。
SCons通过打印输出状态消息来显示它何时在读取SConstruct文件,何时在实际编译目标文件,进而来区分是在调用一个类似Program的编译方法还是在实际地编译这个程序。
看下面这个例子:
print "Calling Program('hello.c')"
Program('hello.c')
print "Calling Program('goodbye.c')"
Program('goodbye.c')
print "Finished calling Program()"
执行SCons,我们看到print语句的输出是在读取Sconstruct文件消息之间,说明了那才是Python语句执行的时候:
% scons
scons: Reading Sconscript files...
Calling Program('hello.c')
Calling Program('goodbye.c')
Finished Calling Program()
scons: done reading SConscript files...
scons: Building targets...
cc -o goodbye.o -c goodbye.c
cc -o goodbye goodbye.o
cc -o hello.o -c hello.c
cc -o hello hello.o
scons: done building targets.
6、使Scons输出更简洁
你已经看到过SCons编译的时候会打印一些消息,那些消息围绕着实际用来编译程序的命令:
scons: Reading SConscript files...
scons: done reading SConscript files.
scons: Building targets...
cl /Fohello.obj /c hello.c /nologo
link /nologo /OUT:hello.exe hello.obj
embedManifestExeCheck(target, source, env)
scons: done building targets.
这些消息反映了SCons工作时候的顺序。
一个缺点就是,这些消息使得输出看起来很混乱。当调用SCons的时候使用-Q选项,可以屏蔽掉那些与实际编译程序命令无关的消息:
C:\>scons -Q
cl /Fohello.obj /c hello.c /nologo
link /nologo /OUT:hello.exe hello.obj
embedManifestExeCheck(target, source, env)