Python scons正在忽略文件目标路径?

Python scons正在忽略文件目标路径?,python,scons,Python,Scons,我在scons 2.3.0中看到了一些奇怪的行为。也许我只是做错了™, 但这似乎应该是明智的 destinations = [base_dir+'lib/', base_dir+'tree/usr/local/lib/'] boost_ver = '1.63.0' boost_libs = (x for x in env['LIBS'] if 'boost_' in x) # eg. 'boost_thread', 'boost_system' for dest in destinations

我在scons 2.3.0中看到了一些奇怪的行为。也许我只是做错了™, 但这似乎应该是明智的

destinations = [base_dir+'lib/', base_dir+'tree/usr/local/lib/']
boost_ver = '1.63.0'
boost_libs = (x for x in env['LIBS'] if 'boost_' in x)
# eg. 'boost_thread', 'boost_system'

for dest in destinations:
    for lib_name in boost_libs:
        lib_so = 'lib'+lib_name+'.so'
        lib_so_ver = lib_so+'.'+boost_ver

        env.Command(dest+lib_so_ver, libsrc+lib_so_ver, Copy("$TARGET","$SOURCE"))
        env.Command(dest+lib_so, dest+lib_so_ver, SymLink)
要点是获取命名库并将它们从
libsrc
复制到每个
目的地
,同时重新创建无版本的符号链接。(
base_dir
libsrc
是绝对路径,但
base_dir
指向scons输出树。)

这对单个目的地很有效,但对任何其他目的地都不会进行复制或链接。我已经尝试使用
env.Depends
添加显式依赖项;我尝试将结果分配给变量,并在以后使用它;似乎什么都不管用

如果我查看
--tree
的输出,总是只列出第一个目标中的文件;任何后续的事件都不会发生。(如果我更改了它们的列出顺序,那么现在排在第一位的就是唯一列出的。)

如果我为每个目的地添加别名目标,并使其
取决于命令的结果,则两个别名目标都出现在树中,但只有第一个别名目标有子项;第二个出现的总是没有孩子

即使我在命令行上明确指定了第二个别名目标,它也不会执行任何操作,也不会在
--树中打印任何子项。只有重新排序目的地,我才能让它做任何事情——当然,另一个停止工作


基本上,它看起来就像任何给定的输入文件都只能执行一个操作,完全忽略多次使用源文件的任何尝试,甚至连警告都没有。这看起来很疯狂。

事实证明,这不是SCON的问题,而是Python的问题。真正的问题™ 这个定义是:

boost_libs = (x for x in env['LIBS'] if 'boost_' in x)
无论出于何种原因(显然我的python fu不够高),这都会导致上面的内部For循环只在第一个目的地执行一次

解决方案是使用方括号:

boost_libs = [x for x in env['LIBS'] if 'boost_' in x]

这将正确地为每个目的地执行内部循环。

您能否告诉我们更多关于
SymLink
方法(?)的功能,以及为什么它似乎不需要任何参数?我在UserGuide/sources中找不到具有此名称的方法/工厂…无论是对于SCons 2.3.0还是最新的2.5.1,都不适用。它只是一个本地定义的python函数(
def SymLink(target,source,env)
),可以实现它的功能。它使用的是标准SCON,与此问题无关。澄清一下:副本和符号链接都适用于单个目的地。副本和符号链接都不适用于任何其他目的地,因为SCON似乎忽略了附加的
命令。关于为什么会发生这种情况,我唯一的理论是,所有目的地之间每对中的第一个命令的源都是相同的。但这似乎是它失败的一个愚蠢的原因,如果这确实是原因的话。我将您的代码片段转换为一个最小的示例SConstruct,它在我这边的SCons v2.3.3下按预期工作。检查我们的#2,如果问题仍然存在,请将其提交给我们的用户邮件列表。根据回答,问题不在于给定的代码,而在于修改的代码。那么问题的原因是什么呢?作为参考,我现在知道了原因——带括号的语法是一个生成器,它只能迭代一次。相反,用方括号表示的是一个列表,可以多次迭代。更让人困惑的是,元组(也使用括号)也可以多次迭代。(元组让人困惑的是,代码以前读过
('boost\u-thread','boost\u-system'))
,这正如预期的那样工作——但在保留括号的同时给它一个表达式会破坏它。显然,这是我不知道生成器的错误,但之前的开发人员使用元组而不是列表,导致了混乱。)