配置SCons使用不同工具进行代码生成和汇编

5 投票
1 回答
3547 浏览
提问于 2025-04-17 06:58

我正在尝试使用 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 只尝试用一个目标文件进行链接(这显然是失败的)。

  1. 我该如何让 SCons 在所有文件上运行这个构建器,并将这些目标文件包含在链接中?
  2. 有没有更好的方法来实现我想做的事情?我刚开始接触 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.

撰写回答