gpt4 book ai didi

scons - 编写一个执行外部命令和 python 函数的自定义构建器

转载 作者:行者123 更新时间:2023-12-01 00:56:17 25 4
gpt4 key购买 nike

我正在寻找编写一个自定义 SCons 生成器:

  • 执行外部命令以产生 foo.temp
  • 然后执行一个python函数来操作foo.temp并生成最终输出文件

  • 我已经提到了以下两个部分,但我不确定将它们“粘合”在一起的正确方法。
  • 18.1. Writing Builders That Execute External Commands
  • 18.4. Builders That Execute Python Functions

  • 我知道 Command 接受要采取的行动列表。但是我如何正确处理该中间文件?理想情况下,中间文件对用户是不可见的——整个构建器看起来是原子操作的。

    这就是我想出的似乎有效的方法。然而 .bin文件不会被自动删除。

    from SCons.Action import Action
    from SCons.Util import is_List
    from SCons.Script import Delete

    _objcopy_builder = Builder(
    action = 'objcopy -O binary $SOURCE $TARGET',
    suffix = '.bin',
    single_source = 1
    )

    def _add_header(target, source, env):
    source = str(source[0])
    target = str(target[0])

    with open(source, 'rb') as src:
    with open(target, 'wn') as tgt:
    tgt.write('MODULE\x00\x00')
    tgt.write(src.read())
    return 0

    _addheader_builder = Builder(
    action = _add_header,
    single_source = 1
    )

    def Elf2Mod(env, target, source, *args, **kw):
    def check_one(x, what):
    if not is_List(x):
    x = [x]
    if len(x) != 1:
    raise StopError('Only one {0} allowed'.format(what))
    return x
    target = check_one(target, 'target')
    source = check_one(source, 'source')

    # objcopy a binary file
    binfile = _objcopy_builder.__call__(env, source=source, **kw)

    # write the module header
    _addheader_builder.__call__(env, target=target, source=binfile, **kw)

    # delete the intermediate binary file
    # TODO: Not working
    Delete(binfile)

    return target

    def generate(env):
    """Add Builders and construction variables to the Environment."""
    env.AddMethod(Elf2Mod, 'Elf2Mod')
    print 'Added Elf2Mod to env {0}'.format(env)

    def exists(env):
    return True

    最佳答案

    这确实可以通过 Command builder 来完成。 , 通过指定操作列表,如下所示:

    Command('foo.temp', 'foo.in',
    ['your_external_action',
    your_python_function])

    请注意 foo.in是来源,您应该相应地命名它。但如果 foo.temp正如您提到的那样是内部的,那么这种方法可能不是最好的方法。

    另一种我觉得更灵活的方法是使用 Custom BuilderGenerator和/或 Emitter .
    Generator是一个 Python 函数,您可以在其中执行实际工作,在您的情况下,它将调用外部命令,也调用 Python 函数。

    Emitter允许您对源和目标进行微调控制。我用了 BuilderEmitter (和 Generator )一次使用 Thrift 输入 IDL 文件执行 C++ 和 Java 代码生成。我必须阅读和处理 Thrift 输入文件才能确切知道哪些文件将被代码生成(哪些是实际目标),以及 Emitter是最好/唯一的方法来做这样的事情。如果您的特定用例不是那么复杂,您可以跳过 Emitter并在对构建器的调用中列出您的源/目标。但是如果你想要 foo.temp要对最终用户透明,那么您将需要一个发射器。

    当使用带有 Generator 和 Emitter 的 Custom Builder 时,SCons 每次都会调用 Emitter 来计算源和依赖项,以了解是否需要调用 Generator。仅当目标之一相对于源而言较旧时,才会调用生成器。

    有很多示例展示了如何在自定义构建器中使用生成器和发射器,所以我不会在这里列出代码,但如果您需要语法等方面的帮助,请告诉我。

    关于scons - 编写一个执行外部命令和 python 函数的自定义构建器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27666431/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com