English 中文(简体)
Why does Scons care that my target is read-only, and how can I convince it to ignore it?
原标题:
  • 时间:2009-12-14 23:01:52
  •  标签:
  • scons

I m trying to put together a debug build of a particularly difficult project layout. One of the things I need to do is to copy recently built DLLs over existing DLLs that are under Source Safe s control, and are therefore read-only. I was hoping to use Scons to manage this, but Scons errors out if your target is read-only. Part of my command is to set it to readable, but my command never executes because scons errors out first. Is there anyway to override this behavior?

Here s a demonstration. As you can see, my "turn off the read-only bit" command never gets run if the read-only bit is set:

C:scsdev	est>type Sconstruct
env = Environment()

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

C:scsdev	est>echo "test" > a.txt

C:scsdev	est>scons -Q b.txt
if exist b.txt c:windowssystem32attrib -r b.txt
Copy("b.txt", "a.txt")

C:scsdev	est>echo "test2" > a.txt

C:scsdev	est>attrib +r b.txt

C:scsdev	est>scons -Q b.txt
scons: *** [b.txt] C:scsdev	est.txt: Access is denied

Update

OK - I ve figured this out by stepping though Scons as it was running. Looks like Scons deletes targets before building them (see _rmv_existing in FS.py, also this page in the scons documentation page). If you encounter this problem, you can mark the target as "Precious", but you ll still have trouble if you use "-c".

No real good solution here. Oh well.

最佳回答

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/

问题回答

use NoClean(target) to disable deleting of generated files while running scons -c.





相关问题
scons hierarchcal builds: propagating builders

I need to be able to tune a construction environment so that I can either build a static or a shared objects in lower levels. Currently, I came up with the following approach: top-level SConstruct: ...

Determining Build Directory from SConscript

I have an SConscript which is being copied to a build directory (variant_dir = ...) for construction. As a workaround for not being able to express dependencies, I m trying to copy some additional ...

Expressing an SConscript s Own Dependencies

I have an SCons project set up as follows: Project/ SConstruct # "SConscript( stuff/SConscript , variant_dir = build ) stuff/ SConscript # "import configuration" ...

How to set ":make" to use scons?

I know there is a way to make vim run scons instead of make when I press :make. I had an option that did this in my ~/.vimrc but I removed it a while ago and forgot what it was.

How to make scons work properly

I m trying to compile the SndObj library from the source. Supposedly it s as easy as just running scons from the top of the SndObj directory. I get this: nhnifong@ubuntu-nate:~/SndObj-2.6.6$ scons ...

热门标签