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

发布于 2024-12-17 16:25:24 字数 878 浏览 6 评论 0原文

我正在尝试使用 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 合作。

I am trying to prepare a build system using SCons. I want to use clang for the code generation phase and a custom compiler toolchain for everything else.

By default, the SCons configuration does not have an explicit step in which the assembly (.s) files are generated.

In order to get around this, I created my own Builder which emits assembly files.

code_generator = Builder(action = '$CC -$LOTS_OF_FLAGS -S $SOURCE -o $TARGET', suffix = '.s')
env.Append(BUILDERS = {'CodeGenerator':code_generator})

I then use this Builder on my source files and pass the resulting NodeList to the Program.

for file in Glob('*.c'):
  sources += env.CodeGenerator(file)

env.Program('say_hello', sources) 

This works well when I do not modify any variables. I get an executable using gcc.

However, when I try to replace the appropriate variables so that SCons uses the custom toolchain (using env.Replace(CC='clang')...), only one assembly file is generated. My custom Builder is not called on any other file and SCons tries to link with only one object file (which obviously fails)

  1. How can I make SCons run the builder on all files and include those
    object files for linking?
  2. Is there a better way to accomplish what I
    am trying to do? I am just beginning to work with SCons.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小女人ら 2024-12-24 16:25:24

SCons 上记录了 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.

There are a large number of keyword arguments for the Builder class that are documented on the SCons man page, that aren't mentioned in the user manual. This is one of the weak points in the documentation for SCons, and has been for some time.

In this case, I believe you are looking for the single_source keyword argument which:

Specifies that this builder expects exactly one source file per call.
Giving more than one source file without target files results in
implicitely calling the builder multiple times (once for each source
given).

Looking at the source for Builder single_source needs to evaluate to True (or an equivalent). So your code can be rewritten with one very minor modification.

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)

Which for a directory with the files: foo.c and bar.c produces the output:

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文