配置SCons使用不同工具进行代码生成和汇编
我正在尝试使用 SCons 来搭建一个构建系统。我想在代码生成阶段使用 clang
,而其他部分则使用自定义的编译工具链。
默认情况下,SCons 的配置没有明确的步骤来生成汇编 (.s)
文件。
为了绕过这个问题,我创建了自己的 Builder
,可以生成汇编文件。
code_generator = Builder(action = '$CC -$LOTS_OF_FLAGS -S $SOURCE -o $TARGET', suffix = '.s')
env.Append(BUILDERS = {'CodeGenerator':code_generator})
然后,我在我的源文件上使用这个 Builder
,并将生成的 NodeList
传递给 Program
。
for file in Glob('*.c'):
sources += env.CodeGenerator(file)
env.Program('say_hello', sources)
当我不修改任何变量时,这个方法运行得很好,我可以使用 gcc
得到一个可执行文件。
但是,当我尝试替换相应的变量,让 SCons 使用自定义工具链(使用 env.Replace(CC='clang')...
)时,只生成了一个汇编文件。我的自定义 Builder
没有在其他文件上被调用,SCons 只尝试用一个目标文件进行链接(这显然是失败的)。
- 我该如何让 SCons 在所有文件上运行这个构建器,并将这些目标文件包含在链接中?
- 有没有更好的方法来实现我想做的事情?我刚开始接触 SCons。
1 个回答
3
在SCons的文档中,有很多关于Builder
类的关键字参数,这些参数在用户手册里没有提到,但在SCons的手册页面上有详细说明。这是SCons文档的一个薄弱环节,已经存在一段时间了。
在这种情况下,我认为你在寻找single_source
这个关键字参数,它的意思是:
指定这个构建器每次调用时只期望一个源文件。如果提供多个源文件而没有目标文件,就会隐式地多次调用这个构建器(每个源文件调用一次)。
查看Builder
的源代码,single_source
需要被评估为True(或者相等的值)。所以你的代码可以稍微修改一下。
env = Environment()
code_generator = Builder(action = '$CC $CCFLAGS -S $SOURCE -o $TARGET',
single_source = 1,
suffix = '.s')
env.Replace(CC= 'clang')
env.Append(BUILDERS = {'CodeGenerator' : code_generator})
sources = env.CodeGenerator(file)
env.Program('say_hello', sources)
对于一个包含文件foo.c和bar.c的目录,输出结果是:
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
clang -S bar.c -o bar.s
as -o bar.o bar.s
clang -S foo.c -o foo.s
as -o foo.o foo.s
clang -o say_hello bar.o foo.o
scons: done building targets.