我正在尝试使用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尝试仅链接一个目标文件(显然失败)
答案 0 :(得分:3)
SCons man page上记录了Builder
类的大量关键字参数,这些参数未在用户手册中提及。这是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.