配置SCons使用单独的工具进行代码生成和汇编

5
我正在尝试使用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
Builder类有大量的关键字参数,这些参数在SCons的man页面记录,但是在用户手册中没有提到。这是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.

即使在提出的修复方案之后,我仍然遇到了同样的问题。但是感谢您在手册页面中提供额外文档的备注。您是正确的,我只参考了用户指南。我会进一步调查并报告结果,如果成功的话。 - Buzzy
你使用的 scons 版本是哪个? - Andrew Walker
在Mac上使用Homebrew安装:脚本:v2.1.0.r5357 引擎:v2.1.0.r5357 - Buzzy
我放弃尝试弄清楚为什么Builder不能在所有文件上运行。为了解决这个问题,我创建了另一个单一源Builder来构建对象文件,而不是使用Program Builder。虽然不是最理想的解决方案,但目前工作得很好。谢谢! - Buzzy
我试图让从scons输出看到的结果更清晰一些,但在homebrew上使用那个版本的scons和一个较旧的clang版本对我有效。 - Andrew Walker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接