我想编写一个定制的SCons生成器:
foo.tempfoo.temp并生成最终的输出文件。我已经提到了以下两个部分,但我不确定将它们“粘合”在一起的正确方法。
我知道Command接受要采取的一系列行动。但是如何正确处理这个中间文件呢?理想情况下,中间文件对用户是不可见的--整个Builder看起来都是原子操作的。
我想出的办法似乎很有效。但是,.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发布于 2014-12-27 13:03:34
这确实可以通过命令生成器来完成,方法是指定一个操作列表,如下所示:
Command('foo.temp', 'foo.in',
['your_external_action',
your_python_function])请注意,foo.in是源,您应该相应地命名它。但是,如果foo.temp是内部的,那么这种方法可能不是最好的方法。
另一种更灵活的方法是将自定义生成器与生成器和/或发射器一起使用。
Generator是一个Python函数,在这里您可以执行实际的工作,在您的示例中,它将调用外部命令,并调用Python函数。
Emitter允许您对源和目标进行微调控制。我曾经使用带有Builder的Emitter (和Generator)来生成C++和Java代码,并使用Generator输入IDL文件。我必须读取和处理the输入文件,才能确切地知道哪些文件将由代码生成(这些文件是实际的目标),而Emitter是这样做的最佳/唯一方法。如果您的特定用例没有那么复杂,您可以跳过Emitter,只需在对构建器的调用中列出源/目标。但是如果你想让foo.temp对最终用户透明,那么你就需要一个发射器。
当使用带有生成器和发射器的自定义生成器时,每次SCons都会调用发射器来计算源和依赖项,以了解是否需要调用生成器。只有当其中一个目标相对于源而言被认为较旧时,才会调用生成器。
有许多例子展示了如何在自定义生成器中使用生成器和发射器,所以我不会在这里列出代码,但是如果您需要语法帮助,请告诉我。
https://stackoverflow.com/questions/27666431
复制相似问题