"__cacheable__"
# Duplicate from source path if we are set up to do this.
if self.duplicate and not self.is_derived() and not self.linked:
- src=self.srcnode()
+ src = self.srcnode()
if src is self:
return Base.exists(self)
+ # At this point, src is meant to be copied in a build directory.
src = src.rfile()
- if src.abspath != self.abspath and src.exists():
- self.do_duplicate(src)
+ if src.abspath != self.abspath:
+ if src.exists():
+ self.do_duplicate(src)
+ # Can't return 1 here because the duplication might
+ # not actually occur if the -n option is being used.
+ else:
+ # The source file does not exist. Make sure no old
+ # copy remains in the build directory.
+ if Base.exists(self) or self.islink():
+ self.fs.unlink(self.path)
+ # Return None explicitly because the Base.exists() call
+ # above will have cached its value if the file existed.
+ return None
return Base.exists(self)
#
dirs = fff.Dirs(['d1', 'd2'])
assert dirs == [d1, d2], map(str, dirs)
+ def test_exists(self):
+ """Test the File.exists() method"""
+ fs = self.fs
+ test = self.test
+
+ src_f1 = fs.File('src/f1')
+ assert not src_f1.exists(), "%s apparently exists?" % src_f1
+
+ test.subdir('src')
+ test.write(['src', 'f1'], "src/f1\n")
+
+ assert not src_f1.exists(), "%s did not cache previous exists() value" % src_f1
+ src_f1.clear()
+ assert src_f1.exists(), "%s apparently does not exist?" % src_f1
+
+ test.subdir('build')
+ fs.BuildDir('build', 'src')
+ build_f1 = fs.File('build/f1')
+
+ assert build_f1.exists(), "%s did not realize that %s exists" % (build_f1, src_f1)
+ assert os.path.exists(build_f1.abspath), "%s did not get duplicated on disk" % build_f1.abspath
+
+ test.unlink(['src', 'f1'])
+ src_f1.clear() # so the next exists() call will look on disk again
+
+ assert build_f1.exists(), "%s did not cache previous exists() value" % build_f1
+ build_f1.clear()
+ build_f1.linked = None
+ assert not build_f1.exists(), "%s did not realize that %s disappeared" % (build_f1, src_f1)
+ assert not os.path.exists(build_f1.abspath), "%s did not get removed after %s was removed" % (build_f1, src_f1)
+
class RepositoryTestCase(_tempdirTestCase):
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test BuildDir handling of removal of source files.
+
+A C++ Program is created and compiled. First, a header is missing. Then
+the header is added and the compilation should succeed, then the header
+is removed and the compilation should fail again.
+
+Previous versions of SCons did not remove the header from the build
+directory after the source directory's header was removed, which caused
+the compilation to succeed even after the source file was removed.
+
+Test case supplied by Patrick Mezard--many thanks.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+#-------------------------------------------------------------------------------
+#1- Create dep.cpp and the SConstruct. dep.h is missing and the build is
+#expected to fail with 2.
+#-------------------------------------------------------------------------------
+
+test.subdir('src')
+
+test.write(['src', 'dep.cpp'], """\
+#include "dep.h"
+
+int main(int argc, char* argv[])
+{
+ return test_dep();
+}
+""")
+
+test.write('SConstruct', """
+env = Environment()
+env.BuildDir('bin', 'src')
+o = env.Object('bin/dep', 'bin/dep.cpp')
+env.Program('bin/dep', o)
+""")
+
+test.run(arguments = '.', stderr=None, status=2)
+
+
+#-------------------------------------------------------------------------------
+#2- Add dep.h and check the build is OK.
+#-------------------------------------------------------------------------------
+
+test.write(['src', 'dep.h'], """\
+#ifndef DEP_H
+#define DEP_H
+
+inline int test_dep()
+{
+ return 1;
+}
+
+#endif //DEP_H
+""")
+
+test.run(arguments = '.')
+
+
+#-------------------------------------------------------------------------------
+#3- Remove dep.h. The build is expected to fail again like in [1].
+#-------------------------------------------------------------------------------
+
+test.unlink(['src', 'dep.h'])
+
+test.run(arguments = '.', stderr=None, status=2)
+
+
+test.pass_test()