4

特に難しいプロジェクト レイアウトのデバッグ ビルドをまとめようとしています。私がしなければならないことの 1 つは、最近ビルドされた DLL を、Source Safe の管理下にある既存の DLL の上にコピーすることです。したがって、読み取り専用です。これを管理するために 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

アップデート

OK - 実行中の Scons をステップ実行して、これを理解しました。Scons はターゲットをビルドする前にターゲットを削除するようです (FS.py を参照してください。scons ドキュメント ページのこの_rmv_existingページも参照してください)。この問題が発生した場合は、ターゲットを「Precious」としてマークできますが、「-c」を使用すると問題が発生します。

ここには本当に良い解決策はありません。しかたがない。

4

2 に答える 2

1

NoClean(target)を使用して、実行中に生成されたファイルの削除を無効にしますscons -c

于 2009-12-24T19:56:22.617 に答える
0

これは、この質問に関連する Windows 固有の問題です。os.unlink()/os.remove()ファイルが読み取り専用の場合、Pythonは Windows で例外を発生させますが、Linux では発生しません。動作に一貫性を持たせるために、os.unlink() にモンキー パッチを適用することにしました。これは、ビルドとクリーニング (-cオプション ) でこれまでに見つけたすべての問題をカバーしています。

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

モンキーパッチの詳細: https://filippo.io/instance-monkey-patching-in-python/

于 2016-07-07T00:28:49.783 に答える