6

我想注入一个“清理”目标,该目标取决于在它关闭之前完成的许多其他目标以及 gzip 的一些日志文件。重要的是我不要过早使用 gzip,因为这会导致某些工具失败。

如何为 Scons 注入清理目标以执行?

例如,我有目标 foo 和 bar。我想注入一个名为“cleanup”的新自定义目标,它依赖于 foo 和 bar 并在它们都完成后运行,而无需用户指定

% scons foo cleanup

我希望他们输入:

% scons foo

但是让 scons 像用户输入的一样执行

% scons foo cleanup

我已经尝试创建清理目标并附加到 sys.argv,但似乎 scons 在到达我的代码时已经处理了 sys.argv,因此它不会处理我手动附加到的“清理”目标系统.argv。

4

3 回答 3

13

您不应该使用_Add_Targets或未记录的功能,您只需将清理目标添加到BUILD_TARGETS

from SCons.Script import BUILD_TARGETS
BUILD_TARGETS.append('cleanup')

如果您使用此记录的目标列表而不是未记录的函数,则 scons 在进行簿记时不会感到困惑。此评论块可在以下位置找到SCons/Script/__init__.py

# BUILD_TARGETS can be modified in the SConscript files.  If so, we
# want to treat the modified BUILD_TARGETS list as if they specified
# targets on the command line.  To do that, though, we need to know if
# BUILD_TARGETS was modified through "official" APIs or by hand.  We do
# this by updating two lists in parallel, the documented BUILD_TARGETS
# list, above, and this internal _build_plus_default targets list which
# should only have "official" API changes.  Then Script/Main.py can
# compare these two afterwards to figure out if the user added their
# own targets to BUILD_TARGETS.

所以我想它是为了改变BUILD_TARGETS而不是调用内部帮助函数

于 2012-03-11T13:43:12.177 回答
3

一种方法是让 gzip 工具依赖于日志文件的输出。例如,如果我们有这个 C 文件,'hello.c':

#include <stdio.h>
int main()
{
    printf("hello world\n");
    return 0;
}

而这个 SConstruct 文件:

#!/usr/bin/python
env = Environment()
hello = env.Program('hello', 'hello.c')
env.Default(hello)
env.Append(BUILDERS={'CreateLog':
    Builder(action='$SOURCE.abspath > $TARGET', suffix='.log')})
log = env.CreateLog('hello', hello)
zipped_log = env.Zip('logs.zip', log)
env.Alias('cleanup', zipped_log)

然后运行“scons cleanup”将以正确的顺序运行所需的步骤:

gcc -o hello.o -c hello.c
gcc -o hello hello.o
./hello > hello.log
zip(["logs.zip"], ["hello.log"])

这不是您指定的内容,但此示例与您的要求之间的唯一区别是“清理”是实际创建 zip 文件的步骤,因此这是您必须运行的步骤。它的依赖关系(运行生成日志的程序,创建该程序)是自动计算的。您现在可以按如下方式添加别名“foo”以获得所需的输出:

env.Alias('foo', zipped_log)
于 2009-04-02T06:49:04.600 回答
1

在 SCons 的 1.1.0.d20081104 版本中,您可以使用私有内部 SCons 方法:

SCons.Script._Add_Targets( [ 'MY_INJECTED_TARGET' ] )

如果用户键入:

% scons foo bar 

上面的代码片段将导致 SCons 表现得好像用户输入了:

% scons foo bar MY_INJECTED_TARGET
于 2009-04-02T16:20:37.637 回答