python - SCons 生成可变数量的目标

标签 python code-generation scons

我正在尝试让 SCons 生成多个目标(直接在 SConscript 中未知数量)。

我有这样的目录:

headers/
  Header1.h
  Header2.h
  Header3.h
  Header4.h
meta/
  headers_list.txt

现在我希望 SConscript 读取 headers_list.txt,根据其内容从 headers/ 目录中选择文件(即它可能只包含 Header1Header3),对于我想使用某些函数生成源代码的每一个。

我一直在尝试使用 env.Command 来做到这一点,但问题是它需要调用者指定目标列表,由于显而易见的原因,在调用 env.Command 时不知道该列表

我唯一能想到的就是运行:

for header in parse( headers_file ):
    source = mangle_source_name_for_header( header )
    env.Command( source, header, generator_action )

但这意味着我将在每次调用 scons 时运行 parse( headers_file )。 如果解析成本高且文件不经常更改,则可以轻松缓存此步骤。

我缺少什么 SConsc 构造/类/技术来实现该缓存?

编辑:

看来我的问题类似于Build-time determination of SCons targets , 但没有人工虚拟文件的技术不是吗?

此外,即使使用临时文件,我也看不出我应该如何将 target 变量从生成可变数量目标的 Command 传递给第二个目标遍历它们。

编辑 2:

This看起来很有前途。

最佳答案

我发现我能做到的唯一方法是使用 emitter。 下面的示例包含 3 个文件:

./
|-SConstruct
|-src/
| |-SConscript
| |-source.txt
|-build/

SConstruct

env = Environment()

dirname = 'build'
VariantDir(dirname, 'src', duplicate=0)

Export('env')

SConscript(dirname+'/SConscript')

src/SConscript

Import('env')

def my_emitter( env, target, source ):
    data = str(source[0])
    target = []
    with open( data, 'r' ) as lines:
        for line in lines:
           line = line.strip()
           name, contents = line.split(' ', 1)
           if not name: continue

           generated_source  = env.Command( name, [], 'echo "{0}" > $TARGET'.format(contents) )
           source.extend( generated_source )
           target.append( name+'.c' )

    return target, source

def my_action( env, target, source ):
    for t,s in zip(target, source[1:]):
        with open(t.abspath, 'w') as tf:
            with open(s.abspath, 'r') as sf:
                tf.write( sf.read() )

SourcesGenerator = env.Builder( action = my_action, emitter = my_emitter )
generated_sources = SourcesGenerator( env, source = 'source.txt' )

lib = env.Library( 'functions', generated_sources )

src/source.txt

a int a(){}
b int b(){}
c int c(){}
d int d(){}
g int g(){}

输出:

$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
echo "int a(){}" > build/a
echo "int b(){}" > build/b
echo "int c(){}" > build/c
echo "int d(){}" > build/d
echo "int g(){}" > build/g
my_action(["build/a.c", "build/b.c", "build/c.c", "build/d.c", "build/g.c"], ["src/source.txt", "build/a", "build/b", "build/c", "build/d", "build/g"])
gcc -o build/a.o -c build/a.c
gcc -o build/b.o -c build/b.c
gcc -o build/c.o -c build/c.c
gcc -o build/d.o -c build/d.c
gcc -o build/g.o -c build/g.c
ar rc build/libfunctions.a build/a.o build/b.o build/c.o build/d.o build/g.o
ranlib build/libfunctions.a
scons: done building targets.

还有一件事我不太喜欢,那就是在每次执行 scons 时解析 headers_list.txt。我觉得只有在文件更改时才应该有一种方法来解析它。我可以手动缓存它,但我仍然希望有一些技巧可以让 SCons 为我处理缓存。

而且我找不到不重复文件的方法(aa.c 相同)。 一种方法是简单地在 my_action 中生成库而不是源(这是我在最终解决方案中使用的方法)。

关于python - SCons 生成可变数量的目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13953964/

相关文章:

python - SCons:如何在 scons 脚本中调用自定义的 python 函数并建立正确的依赖关系

python - 如何在 Python 中将列表列表中的一个值与列表列表中的另一个值进行比较

objective-c - 除了 Objective-C 之外,还有哪些语言可以生成适用于 iPad 的应用程序代码?

c - 存在哪些用于生成 C 代码的工具/IDE/语言

c# - C# 中的表达式树

scons - 用SCons实现 'install'目标

python - 如何将持续时间格式转换为秒?

python - 具有继承性的 SQLAlchemy 自省(introspection)列类型

python - 如何打印整个稀疏矩阵?

macos - 如何在 Mac OS X 上安装 scons