Clean with empty consvar reference deletes all files in the project
This issue was originally created at: 2011-11-11 04:27:06.
This issue was reported by: marvids.
marvids said at 2011-11-11 04:27:06
When passing an undefined environment variable to the Clean command, scons --clean will delete all files it can in the root directory of the project.
Example project that demonstrates the problem:
project_root
|--main.c
|--SConstruct
## SConstruct
env = Environment()
p = env.Program("main.c")
env.Clean(p, "${DUMMY}")
(Contents of main.c is not important)
Output when running
scons -c:
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Cleaning targets ...
Removed .\.sconsign.dblite
Removed .\SConstruct
Removed .\main.c
scons: Could not remove '.': The process cannot access the file because it is being used by another process
scons: done cleaning targets.
WindowsError: [Error 2] The system cannot find the file specified: '.sconsign.dblite':
File "C:\Python27\Lib\site-packages\scons-2.1.0\SCons\Script\Main.py", line 342:
_exec_main(parser, values)
File "C:\Python27\Lib\site-packages\scons-2.1.0\SCons\Script\Main.py", line 306:
_main(parser)
File "C:\Python27\Lib\site-packages\scons-2.1.0\SCons\Script\Main.py", line 070:
nodes = _build_targets(fs, options, targets, target_top)
File "C:\Python27\Lib\site-packages\scons-2.1.0\SCons\Script\Main.py", line 264:
jobs.run(postfunc = jobs_postfunc)
File "C:\Python27\Lib\site-packages\scons-2.1.0\SCons\Job.py", line 113:
postfunc()
File "C:\Python27\Lib\site-packages\scons-2.1.0\SCons\Script\Main.py", line 1261:
SCons.SConsign.write()
File "C:\Python27\Lib\site-packages\scons-2.1.0\SCons\SConsign.py", line 109:
syncmethod()
File "C:\Python27\Lib\site-packages\scons-2.1.0\SCons\dblite.py", line 127:
self._os_unlink(self._file_name)
ajf58 said at 2014-07-07 11:01:22
Still an issue in SCons 2.3.0 on Linux. Given the nature of the issue I suggest increasing the priority of this to P1.
Still broken, and this is kind of ugly. Poked at this a little bit - the problem is actually that if called as env.Clean, the expansion is deferred, and the Clean method doesn't know it's been called with what will be an empty list. Is it allowed to call self.subst to check?
More specifically, this call in Clean:
flist = self.arg2nodes(files, self.fs.Entry)
comes back with '.' if files is passed as a token that is not defined, and thus the current (top) directory is marked for cleaning, with the results noted. I'm not smart enough to know whether there are other calls of arg2nodes that would expect exactly that behavior, and so pushing the responsibility there would be incorrect.
So either arg could have an undefined env var which is undefined yielding . and generally making a mess of things unintentionally..
Or intentionally.. arg..
Added example to my scons-bugswork repo. https://github.com/bdbaddog/scons-bugswork/tree/main/2801
How about an error like this for test case above.
% python ~/devel/scons/git/scons-bugfixes-2/scripts/scons.py -n -c
scons: Reading SConscript files ...
scons: *** Targets specified to Clean() include on which evaluates to an empty string: [${DUMMY}='']
File "/Users/bdbaddog/devel/scons/git/scons-bugswork/2801/SConstruct", line 3, in <module>
I'm wondering if this problem extends to Default as well? It's not going to have the destructive effect that adding to Clean list does, but it also calls arg2nodes without any check whether a token will expand to ..