Scons 二

依赖性:

和makefile一样,scons再次编译是取决于编译文件是否发生了变化。如果编译文件没有发生变化,那么scons是不会继续编译的。会出现如下打印: is up to date。就代表编译文件没有更新。

scons: done reading SConscript files.

scons: Building targets ...

scons: `.' is up to date.

scons: done building targets.

在scons中我们可以指定相应的依赖规则,可以设置依赖 1 MD5签名是否改变,2 文件的操作时间是否改变:Decider(‘MD5’)和Decider(‘timestamp-match’) 或者两种Decider(‘'MD5-timestamp’)

AlwaysBuild:

如果我们想让一个目标文件不管有没有改动,每次执行scons的时候都必须build一次。那么可以采用AlwaysBuild的方法。

test=Program('test.c')

AlwaysBuild(test)

当采用上面的方法的时候,每次执行scons的时候都会执行一次对test的编译

scons: Reading SConscript files ...

cc=gcc

scons: done reading SConscript files.

scons: Building targets ...

gcc -o test.o -c test.c

gcc -o test test.o

scons: done building targets.

当再次执行scons的时候,可以看到不会再次编译test.o但是会编译test

scons: Reading SConscript files ...

cc=gcc

scons: done reading SConscript files.

scons: Building targets ...

gcc -o test test.o

scons: done building targets.

Environment:

在scons脚本中,通过设置environment来达到不同的编译效果。Scons与三种不同的环境类型可以影响scons的脚本行为

1 External Environment:

外部环境是用户运行SCons时用户环境中的变量集。这些变量可以通过Python os.environ字典在SConscript文件中找到

比如我们在Sconstruct中可以import os来导入python的os模块,然后调用os模块中的函数和功能。

2 Construction Environment:

构建环境是在SConscript文件中创建的一个不同的对象,它包含影响SCons如何决定使用什么操作来构建目标,甚至定义应该使用哪个目标的值。从哪个来源建造的。SCons最强大的特性之一是能够创建多个构造环境,包括从现有的构建环境克隆新的自定义构造环境的能力

创建方法如下:

env = Environment()

可以在创建的时候设置编译的参数。、

env = Environment(CC = 'gcc',CCFLAGS = '-O2')

如下例子:

scon=env.Program('scon_test.c',LIBS=['func'],CPPPATH=['./inc'],CCFLAGS='-O2')

scons: Reading SConscript files ...

cc=gcc

scons: done reading SConscript files.

scons: Building targets ...

gcc -o scon_test.o -c -O2 -Iinc scon_test.c

gcc -o scon_test scon_test.o -Lsrc -lfunc

scons: done building targets.

也可以从通过字典的方式来查看Environment中的配置

env = Environment()

print("cc=%s" % env['CC'])

 

通过Dictionary的方式可以得到所有Environment的字典集合。

env = Environment(FOO='foo', BAR='bar')

cvars = env.Dictionary()

for key in ['OBJSUFFIX', 'LIBSUFFIX', 'PROGSUFFIX']:

print("key = %s, value = %s" % (key, cvars[key]))

 

还可以通过subst的方式,并且访问的关键字前需要加上$符号。

env = Environment()

print("CC is: %s"%env.subst('$CC'))

 

默认配置:

所有的Builder, Program和Library功能都有一个默认的配置进行编译构建,这个默认配置就是DefaultEnvironment,通过调用和改写DefaultEnvironment中的配置可以达到修改默认配置的目的。比如下面的方式就可以使CC采用/usr/local/bin/gcc 来进行编译

DefaultEnvironment(CC='/usr/local/bin/gcc')

 

多个构建环境:

在一个工程下,可能我们需要对不同的文件进行不同方式的编译,比如有些文件需要带-O2的方式编译,有些文件需要带-g(debug)的方式编译。我们可以设定多个不同的Envrionment对象来达标此目的

opt = Environment(CCFLAGS = '-O2')

dbg = Environment(CCFLAGS = '-g')

opt.Program('foo', 'foo.c')

dbg.Program('bar', 'bar.c')

这样编译的时候就可以根据不同的Environment设置来进行编译

cc -o bar.o -c -g bar.c

cc -o bar bar.o

cc -o foo.o -c -O2 foo.c

cc -o foo foo.o

 

克隆环境:

前面讲到多个构建环境,每个环境的配置是独立的。但是如果我想在之前的一个环境上做扩展,那么就可以用到clone的功能。比如下面的方式。

env = Environment(CC = 'gcc')

opt = env.Clone(CCFLAGS = '-O2')

dbg = env.Clone(CCFLAGS = '-g')

env.Program('foo', 'foo.c')

o = opt.Object('foo-opt', 'foo.c')

opt.Program(o)

d = dbg.Object('foo-dbg', 'foo.c')

dbg.Program(d)

输出如下:通过在env上做克隆,并且加入自己的CCFLAGS变量,那么env, opt,dbg都采用的是gcc方式,但是编译参数完全不一样。

gcc -o foo.o -c foo.c

gcc -o foo foo.o

gcc -o foo-dbg.o -c -g foo.c

gcc -o foo-dbg foo-dbg.o

gcc -o foo-opt.o -c -O2 foo.c

gcc -o foo-opt foo-opt.o

 

Replace方法:

当需要修改Environment的配置的时候,可以用replace的方法

env = Environment(CCFLAGS = '-DDEFINE1')

env.Replace(CCFLAGS = '-DDEFINE2')

env.Program('foo.c')

也可以用replace方法去添加一个不在Environment中存在的配置

env = Environment()

env.Replace(NEW_VARIABLE = 'xyzzy')

print("NEW_VARIABLE = %s"%env['NEW_VARIABLE'])

 

Append方法:

想要在已有的配置里面添加选项可以用到append方法

env = Environment(CCFLAGS = ['-DMY_VALUE'])

env.Append(CCFLAGS = ['-DLAST'])

env.Program('foo.c')

这样在编译的时候就有多个编译选项出来

cc -o foo.o -c -DMY_VALUE -DLAST foo.c

cc -o foo foo.o

执行环境是在执行外部命令(例如编译器或链接器)以生成一个或多个目标

还有AppendUnique的方法可以保证每次的添加不重复,比如下面的-g,如果CCFLAGS中没有-g的选项,则可以添加进去

env.AppendUnique(CCFLAGS=['-g'])

 

如果想将某个配置放在最前面,则要采用Prepend

env = Environment(CCFLAGS = ['-DMY_VALUE'])

env.Prepend(CCFLAGS = ['-DFIRST'])

env.Program('foo.c')

-DFIRST将会在-DMY_VALUE的前面

cc -o foo.o -c -DFIRST -DMY_VALUE foo.c

cc -o foo foo.o

 

3 Execution Environment

执行环境中,参数都保存在$ENV变量中,这里面最重要的就是PATH变量。PATH变量在LINUX中的默认值为 /usr/local/bin:/bin:/usr/bin. 如果想扩展我们自己的PATH值,可以采用下面的方法对ENV值进行配置

path = ['/usr/local/bin', '/bin', '/usr/bin']

env = Environment(ENV = {'PATH' : path})

env['ENV']['PATH'] = ['/usr/local/bin', '/bin', '/usr/bin']

也可以采用PrependENVPath和 AppendENVPath的方式添加

env.PrependENVPath('PATH','/home/maple/scons_prj')

env.AppendENVPath('LIB', '/usr/local/lib')

原文地址:https://www.cnblogs.com/zhanghongfeng/p/12792231.html