4

我正在尝试将一个特别困难的项目布局的调试版本组合在一起。我需要做的一件事是将最近构建的 DLL 复制到现有 DLL 上,这些 DLL 受 Source Safe 的控制,因此是只读的。我希望使用 Scons 来管理这个,但是如果你的目标是只读的,Scons 就会出错。我的部分命令是将其设置为可读,但我的命令永远不会执行,因为 scons 首先出错。有没有办法覆盖这种行为?

这是一个演示。如您所见,如果设置了只读位,我的“关闭只读位”命令将永远不会运行:

C:\scs\dev\test>type Sconstruct
env = Environment()

env.Command(
    "b.txt", "a.txt",
        [
        r"if exist $TARGET c:\windows\system32\attrib -r $TARGET",
        Copy("$TARGET", "$SOURCE")
        ]
    )

C:\scs\dev\test>echo "test" > a.txt

C:\scs\dev\test>scons -Q b.txt
if exist b.txt c:\windows\system32\attrib -r b.txt
Copy("b.txt", "a.txt")

C:\scs\dev\test>echo "test2" > a.txt

C:\scs\dev\test>attrib +r b.txt

C:\scs\dev\test>scons -Q b.txt
scons: *** [b.txt] C:\scs\dev\test\b.txt: Access is denied

更新

好的 - 我已经通过在 Scons 运行时踩到它来解决这个问题。看起来 Scons 在构建目标之前会删除它们(请参阅_rmv_existingFS.py,以及 scons 文档页面中的页面)。如果遇到这个问题,可以将目标标记为“Precious”,但是如果使用“-c”,还是会遇到麻烦。

这里没有真正好的解决方案。那好吧。

4

2 回答 2

1

使用 NoClean(target) 在运行时禁用删除生成的文件scons -c

于 2009-12-24T19:56:22.617 回答
0

This is a Windows-specific issue related to this question. Python os.unlink()/os.remove() raise exception on Windows, when a file is read-only, but they won't on Linux. To have consistent behavior, I resorted to monkey-patching os.unlink(). This covers all the issues I found so far in building and cleaning (-c option).

import os, stat
def _os_force_unlink(path):
    """Monkey-patch for os.unlink() to enable removing read-only files. 
    Need for consistency between platforms: os.unlink raises exception on Windows 
    (but not on Linux), when path is read-only.
    Unfixed SCons bug: http://scons.tigris.org/issues/show_bug.cgi?id=2693

    SCons uses os.unlink in several places. To avoid patching multiple functions,
    we patch the os function and use the lucky fact that os.remove does the same,
    so we can still get the normal OS behavior. SCons also uses os.remove(), 
    but not in places that affect this particular issue, so os.remove() stays as is.

    Note: this affects os.unlink() in all user code that runs in context of this set-up.
    """
    if not os.access(path, os.W_OK):
        os.chmod(path, stat.S_IWRITE)
    return os.remove(path) 

# Put this in some common place, like top of SConstruct
if <determine that platform is Windows>
    # Sufficient for SCons 2.5.0. We may need to patch more, if future SCons changes things
    os.unlink = _os_force_unlink

More on monkey-patching: https://filippo.io/instance-monkey-patching-in-python/

于 2016-07-07T00:28:49.783 回答