Why does Scons make sure my goal is read-only and how can I convince it to ignore it?

I am trying to build a debug assembly of a particularly complex project layout. One of the things I need to do is copy the newly created DLL files on top of the existing DLL files that are under the control of Source Safe and therefore are read-only. I was hoping to use Scons to control this, but Scons errors if your target is read-only. Part of my command is to set it to readability, but my command is never executed because scons errors in the first place. Is there any way to reject this behavior?

Here is a demo. As you can see, my β€œturn off read-only bit” command never starts if the read-only bit is set:

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 

Update

OK. I realized this by stepping though Skins worked. It seems that Scons deletes targets before they are created (see _rmv_existing in FS.py, as well as this page on the scons documentation page). If you encounter this problem, you can mark the target as "Jewel", but you will still have a problem if you use "-c".

There is no real good solution. Oh good.

+4
source share
2 answers

This is a Windows related issue with this issue . Python os.unlink()/os.remove() raises an exception on Windows when a file is read-only, but it will not work on Linux. To have consistent behavior, I resorted to the os.unlink () monkey fix. This covers all the problems that I have found so far in the assembly and cleaning process (option -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 

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

0
source

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

+1
source

All Articles