scons:更改单个源文件的编译标志

时间:2013-10-04 18:39:39

标签: scons

我有一个相当复杂的scons系统,有几个子目录,有许多库和可执行文件。 目前,每个SConscript都有自己的克隆环境,因此我可以在每个SConscript的基础上轻松更改CFLAGS(或任何其他可用的),但我想更改每个目标,甚至是每个目标文件。目标

我创建了一个简单的例子SConscript和SConstruct来解释这个问题,如下所示。

SConstruct:

env = Environment()
env['CFLAGS'] = '-O2'
env.SConscript('SConscript', 'env')

SConscript:

Import('env')
env=env.Clone()
env.Program('foo', ['foo.c', 'bar.c'])

如果我运行scons,foo.c和bar.c都会使用-O2标志进行编译。我可以通过在SConscript中添加env['CFLAGS'] = '...'来轻松更改SConscript范围内的标志,但是我要说我想用-O2编译foo.c,但是bar.c完全调试,{{1} }。我该怎么做(以最简单的方式)?

该示例使用gcc,但我想要可以与任何编译器一起使用的东西。

对性能敏感的项目经常会发生这种情况,在这些项目中,在没有优化的情况下编译所有内容会导致不可接受的性能,但是需要调试一个文件(或其中的一部分)。

2 个答案:

答案 0 :(得分:6)

最简单的单行答案可能只是用这个替换你的程序行:

env.Program('foo', ['foo.c', env.Object('bar.c', CFLAGS='-g')])

因为Program可以使用Object节点和源文件,并且可以覆盖任何构建器中的任何构造变量(这里,我们在Object构建器调用中覆盖CFLAGS)。如果您想将Object划分为自己的行以便清晰起见:

debug_objs = env.Object('bar.c', CFLAGS='-g')
env.Program('foo', ['foo.c', debug_objs])

当然,如果达到极限,你就可以获得像Avatar33这样的系统。

答案 1 :(得分:4)

我认为这在scons中比在make中更难,你可以只清理所需的目标并使用调试标志重建。然后,这将只重建一个特定的对象。

您的特定项目的解决方案取决于它的大小以及开发人员准备投入多少精力。 所以这是一个粗略的解决方案,您可以在命令行中指定要使用debug编译而不进行优化的源文件,其余的将使用-O2进行编译。

在你的SConsctruct中另外一行来获取我们想要通过命令行选项调试来编译的源文件:

    env = Environment()
    env['CFLAGS'] = '-O2'
    AddOption('--debug-targets', dest='debug-targets', type='string')
    env.SConscript('SConscript', 'env')

现在在SConscript文件中:

    Import('env')
    env=env.Clone()
    debug_env = env.Clone()
    debug_env['CFLAGS'] = '-g -O0'

    normal_src = ['foo.c', 'bar.c']
    debug_src = []

    #Add src specified via the command line to the debug build 
    if GetOption('debug-targets'):
        for x in GetOption('debug-targets').split(','):
             if x in normal_src:
                normal_src.remove(x)
                debug_src.append(x)

    normal_obj = env.Object(normal_src)
    debug_obj = debug_env.Object(debug_src)
    all_obj = normal_obj + debug_obj
    env.Program('foo', all_obj)

使用我们的调试目标标志运行我们的scons:

    scons -Q      
    gcc -o bar.o -c -O2 bar.c
    gcc -o foo.o -c -O2 foo.c
    gcc -o foo foo.o bar.o

但是现在我们要用调试信息编译bar.c:

    scons -Q --debug-targets=bar.c 
    gcc -o bar.o -c -g -O0 bar.c
    gcc -o foo foo.o bar.o

因此,这会给构建系统增加一些复杂性,但是如果您不需要从命令行指定调试目标,那么开发人员显然可以将normal_src列表中的源切换到debug_src。 对于您的特定环境,可能有很多方法可以改进和微调这个