如何让scons将一个目录本身视为目标?

4

我正在尝试设置一个包含外部工具的构建过程,该工具会生成一个目录作为输出(对于好奇的人来说是doxyindexer)。到目前为止,我基本上已经有了以下这些命令:

target = "doxysearch.db/iamchert"
doxygen.Doxyindexer(target,["project1.xml","project2.xml","project3.xml"])
Default([target])
Default(Install(ARGUMENTS["cgibin"],"doxysearch.db"))

我遇到的问题是,我认为我想让目标(target)是目录本身,而不是目录中的某个随机文件。我无法使用glob来获取目标,因为在我构建它之前,目标并不存在,我也不想假定Dimitri可能会更改什么!当我将目录用作目标时,会出现以下错误:
TypeError: Tried to lookup Dir 'doxysearch.db' as a File.:

这就是我选择iamchert作为目标的原因。这些行看起来都按预期工作,即使我的方法有些取巧。然而,我无法让最后一行工作。我需要将doxysearch.db目录复制到cgi-bin目录中,用户在命令行中指定了该目录。也许有人可以解释如何正确执行此步骤?当涉及到scons时,我是新手!我很难通过搜索引擎找到答案,因为所有相关的搜索关键字都太常见了,无法找到具体帮助!
2个回答

6

SCons实际上将目录中的所有文件视为该目录的依赖项。虽然有一些需要处理的棘手问题,但在像这样简单的情况下,它应该可以正常工作。

您需要的是未记录的target_factory构建器标志。当您定义Doxyindexer时,请按以下方式执行:

doxyindexer = Builder(..., target_factory=env.fs.Dir)

并让您的构建器返回文件夹本身。这样应该可以避免您遇到的TypeError错误。


3

我不确定SCons在目标为目录时能否很好地工作。问题是:SCons应该如何确定目录是否已更改,以知道它是否应该构建?显然的答案是,如果目录中有更多或更少的文件,则认为目录已更改,但我认为SCons目前没有进行此检查,您可能需要自己创建构建器来解决这个问题。

我做了以下示例来测试这一点,但它从未构建成功:

env = Environment()
env.Command(target = 'targetDir',
            source = 'srcTextFile',
            action = Copy("$TARGET", "$SOURCE"))

当我执行SCons时,总是得到相同的结果:
scons: '.' is up to date

关于你的SCons代码,我认为以下方式可以更好地工作:

targetDir = "doxysearch.db/iamchert"
srcFiles = ["project1.xml","project2.xml","project3.xml"]

doxygenTarget = doxygen.Doxyindexer(targetDir, srcFiles)

    # This may need to be called via the Command() builder like this:
    # cmd = "doxygen.Doxyindexer("$TARGET", "$SOURCE")
    # doxygenTarget = env.Command(target=targetDir, source=srcFiles, action=cmd)

# This call to Default isnt really necessary
Default(doxygenTarget)
Install(ARGUMENTS["cgibin"], doxygenTarget)

我猜问题在于如何计算目标目录的“年龄”。一个hack的方法可能是将目录打成tar包,然后将其用作目标。我认为如果这种方法可行,那么Scons可以在幕后实现某种方式来完成它。但听起来你是在说Scons没有这个能力。 - amos
@amos,在SCons中进行此类检查肯定是可行的,因为它非常可扩展,但目前这种行为尚未实现。除了我提到的如果一个目录有更多或更少的文件,则认为该目录已更改之外,有些人可能会认为如果其中的文件已更改,则目录已更改。这可能很快变得复杂和低效,因为它可以扩展到子目录。 - Brady

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接