SCons生成可变数量的目标 [英] SCons to generate variable number of targets

查看:95
本文介绍了SCons生成可变数量的目标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获取 SCons 来生成多个目标(中直接未知的数字)。

I am trying to get SCons to generate multiple targets (number unknown directly in SConscript).

我的目录如下:

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

现在我希望SConscript读取 headers_list.txt ,根据其内容从 headers中选择文件/ 目录(即它可能仅包含 Header1 Header3 )我想使用某些功能生成源代码。

Now I want SConscript to read headers_list.txt, basing on its contents pick files from headers/ directory (i.e. it might contain only Header1 and Header3), for each of those I want to generate source using some function.

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

I have been trying to use env.Command to do that, but the issue is that it requires caller to specify targets list which for obvious reasons is not known when invoking env.Command.

我唯一能想到的是运行:

The only thing I can think of is running:

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

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

But this means I will be running parse( headers_file ) each time I invoke scons. If parsing is costly and the file is not often changed this step could be easily cached.

我缺少实现该目标的SConsc构造/类/技术

What SConsc construct/class/technique I am missing to achieve that caching?

编辑:

似乎我的问题与 SCons目标的构建时确定,但没有人工假人的技术文件?

It seems my question is similar to Build-time determination of SCons targets, but isn't there a technique without artificial dummy file?

此外,即使有临时文件,我也看不到应该如何传递 target 变量从 Command 生成可变数量的目标到第二个目标进行迭代。

Also, even with temporary file, I don't see how I am supposed to pass target variable from Command that generates variable number of targets to second one that would iterate over them.

编辑2 :

This looks promising.

推荐答案

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

The only way I found I can do it is with emitter. Below example consists of 3 files:

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

SConstruct

SConstruct

env = Environment()

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

Export('env')

SConscript(dirname+'/SConscript')

src / 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

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.

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

Also this has one thing I don't really like, which is parsing of headers_list.txt with each scons execution. I feel like there should be a way to parse it only if the file changed. I could cache it by hand, but I still hope there is some trick to make SCons handle that caching for me.

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

And I couldn't find a way to not duplicate files (a and a.c being the same). One way would be to simply generate library in my_action instead of sources (which is approach I used in my final solution).

这篇关于SCons生成可变数量的目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆