diff options
| author | William Deegan <bill@baddogconsulting.com> | 2015-09-21 17:03:12 (GMT) |
|---|---|---|
| committer | William Deegan <bill@baddogconsulting.com> | 2015-09-21 17:03:12 (GMT) |
| commit | 0941093e0e5a030faa49968457638a3a6aee7ad8 (patch) | |
| tree | 6d33513c14eb6eac0531dd050de0ecca4c39bd79 /test/VariantDir | |
| download | SCons-2.4.0.zip SCons-2.4.0.tar.gz SCons-2.4.0.tar.bz2 | |
release 2.4.02.4.0
Diffstat (limited to 'test/VariantDir')
| -rw-r--r-- | test/VariantDir/CPPPATH-subdir.py | 77 | ||||
| -rw-r--r-- | test/VariantDir/Clean.py | 77 | ||||
| -rw-r--r-- | test/VariantDir/File-create.py | 76 | ||||
| -rw-r--r-- | test/VariantDir/SConscript-variant_dir.py | 277 | ||||
| -rw-r--r-- | test/VariantDir/VariantDir.py | 407 | ||||
| -rw-r--r-- | test/VariantDir/errors.py | 178 | ||||
| -rw-r--r-- | test/VariantDir/guess-subdir.py | 75 | ||||
| -rw-r--r-- | test/VariantDir/include-subdir.py | 82 | ||||
| -rw-r--r-- | test/VariantDir/nested-sconscripts.py | 70 | ||||
| -rw-r--r-- | test/VariantDir/no-execute.py | 97 | ||||
| -rw-r--r-- | test/VariantDir/reflect.py | 142 | ||||
| -rw-r--r-- | test/VariantDir/removed-files.py | 105 | ||||
| -rw-r--r-- | test/VariantDir/under.py | 100 |
13 files changed, 1763 insertions, 0 deletions
diff --git a/test/VariantDir/CPPPATH-subdir.py b/test/VariantDir/CPPPATH-subdir.py new file mode 100644 index 0000000..2f41094 --- /dev/null +++ b/test/VariantDir/CPPPATH-subdir.py @@ -0,0 +1,77 @@ +#!/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 handling of the current directory (.) in CPPPATH when +the include path contains a subdirectory. + +This tests for a regression found in 0.96.90 by Chad Austin. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('src', ['src', 'glscry']) + +test.write('SConstruct', """\ +env = Environment() +Export('env') +SConscript(dirs=['src'], variant_dir='build', duplicate=0) +""") + + +test.write(['src', 'SConscript'], """\ +SConscript(dirs=['glscry']) +""") + + +test.write(['src', 'glscry', 'SConscript'], """\ +Import('*') +env = env.Clone() +env.Append(CPPPATH=['.']) +env.Library('foo', 'foo.c') +""") + +test.write(['src', 'glscry', 'foo.c'], """\ +#include <foo.h> +int foo(void) { return 0; } +""") + + +test.write(['src', 'glscry', 'foo.h'], "\n") + +test.run(arguments = '.', + stderr = TestSCons.noisy_ar, + match = TestSCons.match_re_dotall) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/VariantDir/Clean.py b/test/VariantDir/Clean.py new file mode 100644 index 0000000..d1e0bb8 --- /dev/null +++ b/test/VariantDir/Clean.py @@ -0,0 +1,77 @@ +#!/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__" + +""" +Verify that we can Clean() files in a VariantDir() that's underneath us. +(At one point this didn't work because we were using str() instead of +abspath to remove the files, which would interfere with the removal by +returning a path relative to the VariantDir(), not the top-level SConstruct +directory, if the source directory was the top-level directory.) +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +VariantDir('build0', '.', duplicate=0) +VariantDir('build1', '.', duplicate=1) + +def build_sample(target, source, env): + targetdir = str(target[0].dir) + target = str(target[0]) + open(target, 'wb').write(open(str(source[0]), 'rb').read()) + open(targetdir+'/sample.junk', 'wb').write('Side effect!\\n') + +t0 = Command("build0/sample.out", "sample.in", build_sample) +t1 = Command("build1/sample.out", "sample.in", build_sample) + +Clean(t0, 'build0/sample.junk') +Clean(t1, 'build1/sample.junk') +""") + +test.write('sample.in', "sample.in\n") + +test.run(arguments = '.') + +test.must_match(['build0', 'sample.out'], "sample.in\n") +test.must_exist(['build0', 'sample.junk']) + +test.must_match(['build1', 'sample.out'], "sample.in\n") +test.must_exist(['build1', 'sample.junk']) + +test.run(arguments = '-c .') + +test.must_not_exist(['build', 'sample.out']) +test.must_not_exist(['build', 'sample.junk']) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/VariantDir/File-create.py b/test/VariantDir/File-create.py new file mode 100644 index 0000000..725404c --- /dev/null +++ b/test/VariantDir/File-create.py @@ -0,0 +1,76 @@ +#!/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__" + +""" +Verify that explicit use of File() Nodes in a VariantDir, followed by +*direct* creation of the file by Python in the SConscript file itself, +works correctly, with both duplicate=0 and duplicate=1. + +Right now it only works if you explicitly str() the Node before the file +is created on disk, but we at least want to make sure that continues +to work. The non-str() case, which doesn't currently work, is captured +here but commented out. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('src') + +test.write('SConstruct', """\ +SConscript('src/SConscript', variant_dir='build0', chdir=1, duplicate=0) +SConscript('src/SConscript', variant_dir='build1', chdir=1, duplicate=1) +""") + +test.write(['src', 'SConscript'], """\ +#f1_in = File('f1.in') +#Command('f1.out', f1_in, Copy('$TARGET', '$SOURCE')) +#open('f1.in', 'wb').write("f1.in\\n") + +f2_in = File('f2.in') +str(f2_in) +Command('f2.out', f2_in, Copy('$TARGET', '$SOURCE')) +open('f2.in', 'wb').write("f2.in\\n") +""") + +test.run(arguments = '--tree=all .') + +#test.must_match(['build0', 'f1.out'], "f1.in\n") +test.must_match(['build0', 'f2.out'], "f2.in\n") + +#test.must_match(['build1', 'f1.out'], "f1.in\n") +test.must_match(['build1', 'f2.out'], "f2.in\n") + +test.up_to_date(arguments = '.') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/VariantDir/SConscript-variant_dir.py b/test/VariantDir/SConscript-variant_dir.py new file mode 100644 index 0000000..068c312 --- /dev/null +++ b/test/VariantDir/SConscript-variant_dir.py @@ -0,0 +1,277 @@ +#!/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__" + +""" +Verify that specifying a variant_dir argument to SConscript works properly. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +all1 = test.workpath('test', 'build', 'var1', 'all') +all2 = test.workpath('test', 'build', 'var2', 'all') +all3 = test.workpath('test', 'build', 'var3', 'all') +all4 = test.workpath('test', 'build', 'var4', 'all') +all5 = test.workpath('build', 'var5', 'all') +all6 = test.workpath('build', 'var6', 'all') +all7 = test.workpath('build', 'var7', 'all') +all8 = test.workpath('build', 'var8', 'all') +all9 = test.workpath('test', 'build', 'var9', 'src', 'all') + +test.subdir('test') + +test.write(['test', 'SConstruct'], """ +src = Dir('src') +alt = Dir('alt') +var1 = Dir('build/var1') +var2 = Dir('build/var2') +var3 = Dir('build/var3') +var4 = Dir('build/var4') +var5 = Dir('../build/var5') +var6 = Dir('../build/var6') +var7 = Dir('../build/var7') +var8 = Dir('../build/var8') +var9 = Dir('../build/var9') + +def cat(env, source, target): + target = str(target[0]) + f = open(target, "wb") + for src in source: + f.write(open(str(src), "rb").read()) + f.close() + +env = Environment(BUILDERS={'Cat':Builder(action=cat)}, + BUILD='build') + +Export("env") + +SConscript('src/SConscript', variant_dir=var1) +SConscript('src/SConscript', variant_dir='build/var2', src_dir=src) + +SConscript('src/SConscript', variant_dir='build/var3', duplicate=0) + +#XXX We can't support var4 and var5 yet, because our VariantDir linkage +#XXX is to an entire source directory. We haven't yet generalized our +#XXX infrastructure to be able to take the SConscript file from one source +#XXX directory, but the rest of the files from a different one. +#XXX SConscript('src/SConscript', variant_dir=var4, src_dir=alt, duplicate=0) + +#XXX SConscript('src/SConscript', variant_dir='../build/var5', src_dir='alt') +SConscript('src/SConscript', variant_dir=var6) + +SConscript('src/SConscript', variant_dir=var7, src_dir=src, duplicate=0) +env.SConscript('src/SConscript', variant_dir='../$BUILD/var8', duplicate=0) + +# This tests the fact that if you specify a src_dir that is above +# the dir a SConscript is in, that we do the intuitive thing, i.e., +# we set the path of the SConscript accordingly. The below is +# equivalent to saying: +# +# VariantDir('build/var9', '.') +# SConscript('build/var9/src/SConscript') +SConscript('src/SConscript', variant_dir='build/var9', src_dir='.') +""") + +test.subdir(['test', 'src'], ['test', 'alt']) + +test.write(['test', 'src', 'SConscript'], """ +Import("env") +env.Cat('aaa.out', 'aaa.in') +env.Cat('bbb.out', 'bbb.in') +env.Cat('ccc.out', 'ccc.in') +env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out']) +""") + +test.write('test/src/aaa.in', "test/src/aaa.in\n") +test.write('test/src/bbb.in', "test/src/bbb.in\n") +test.write('test/src/ccc.in', "test/src/ccc.in\n") + +test.write('test/alt/aaa.in', "test/alt/aaa.in\n") +test.write('test/alt/bbb.in', "test/alt/bbb.in\n") +test.write('test/alt/ccc.in', "test/alt/ccc.in\n") + +test.run(chdir='test', arguments = '. ../build') + +all_src = "test/src/aaa.in\ntest/src/bbb.in\ntest/src/ccc.in\n" +all_alt = "test/alt/aaa.in\ntest/alt/bbb.in\ntest/alt/ccc.in\n" + +test.must_match(all1, all_src) +test.must_match(all2, all_src) +test.must_match(all3, all_src) +#XXX We can't support var4 and var5 yet, because our VariantDir linkage +#XXX is to an entire source directory. We haven't yet generalized our +#XXX infrastructure to be able to take the SConscript file from one source +#XXX directory, but the rest of the files from a different one. +#XXX test.must_match(all4, all_alt) +#XXX test.must_match(all5, all_alt) +test.must_match(all6, all_src) +test.must_match(all7, all_src) +test.must_match(all8, all_src) +test.must_match(all9, all_src) + +import os +import stat +def equal_stats(x,y): + x = os.stat(x) + y = os.stat(y) + return (stat.S_IMODE(x[stat.ST_MODE]) == stat.S_IMODE(y[stat.ST_MODE]) and + x[stat.ST_MTIME] == y[stat.ST_MTIME]) + +# Make sure we did duplicate the source files in build/var1, +# and that their stats are the same: +for file in ['aaa.in', 'bbb.in', 'ccc.in']: + test.must_exist(test.workpath('test', 'build', 'var1', file)) + test.fail_test(not equal_stats(test.workpath('test', 'build', 'var1', file), + test.workpath('test', 'src', file))) + +# Make sure we did duplicate the source files in build/var2, +# and that their stats are the same: +for file in ['aaa.in', 'bbb.in', 'ccc.in']: + test.must_exist(test.workpath('test', 'build', 'var2', file)) + test.fail_test(not equal_stats(test.workpath('test', 'build', 'var2', file), + test.workpath('test', 'src', file))) + +# Make sure we didn't duplicate the source files in build/var3. +test.must_not_exist(test.workpath('test', 'build', 'var3', 'aaa.in')) +test.must_not_exist(test.workpath('test', 'build', 'var3', 'bbb.in')) +test.must_not_exist(test.workpath('test', 'build', 'var3', 'ccc.in')) + +#XXX We can't support var4 and var5 yet, because our VariantDir linkage +#XXX is to an entire source directory. We haven't yet generalized our +#XXX infrastructure to be able to take the SConscript file from one source +#XXX directory, but the rest of the files from a different one. +#XXX Make sure we didn't duplicate the source files in build/var4. +#XXXtest.must_not_exist(test.workpath('test', 'build', 'var4', 'aaa.in')) +#XXXtest.must_not_exist(test.workpath('test', 'build', 'var4', 'bbb.in')) +#XXXtest.must_not_exist(test.workpath('test', 'build', 'var4', 'ccc.in')) + +#XXX We can't support var4 and var5 yet, because our VariantDir linkage +#XXX is to an entire source directory. We haven't yet generalized our +#XXX infrastructure to be able to take the SConscript file from one source +#XXX directory, but the rest of the files from a different one. +#XXX Make sure we did duplicate the source files in build/var5, +#XXX and that their stats are the same: +#XXXfor file in ['aaa.in', 'bbb.in', 'ccc.in']: +#XXX test.must_exist(test.workpath('build', 'var5', file)) +#XXX test.fail_test(not equal_stats(test.workpath('build', 'var5', file), +#XXX test.workpath('test', 'src', file))) + +# Make sure we did duplicate the source files in build/var6, +# and that their stats are the same: +for file in ['aaa.in', 'bbb.in', 'ccc.in']: + test.must_exist(test.workpath('build', 'var6', file)) + test.fail_test(not equal_stats(test.workpath('build', 'var6', file), + test.workpath('test', 'src', file))) + +# Make sure we didn't duplicate the source files in build/var7. +test.must_not_exist(test.workpath('build', 'var7', 'aaa.in')) +test.must_not_exist(test.workpath('build', 'var7', 'bbb.in')) +test.must_not_exist(test.workpath('build', 'var7', 'ccc.in')) + +# Make sure we didn't duplicate the source files in build/var8. +test.must_not_exist(test.workpath('build', 'var8', 'aaa.in')) +test.must_not_exist(test.workpath('build', 'var8', 'bbb.in')) +test.must_not_exist(test.workpath('build', 'var8', 'ccc.in')) + +################### +test.subdir('test2') + +test.write(['test2', 'SConstruct'], """\ +SConscript('SConscript', variant_dir='Build', src_dir='.', duplicate=0) +""") + +test.write(['test2', 'SConscript'], """\ +env = Environment() +foo_obj = env.Object('foo.c') +env.Program('foo', [foo_obj, 'bar.c']) +""") + +test.write(['test2', 'bar.c'], r""" +#include <stdio.h> +#include <stdlib.h> + +void +bar(void) { + printf("bar.c\n"); +} +""") + +test.write(['test2', 'foo.c'], r""" +#include <stdio.h> +#include <stdlib.h> + +extern void +bar(void); + +int +main(int argc, char *argv[]) { + bar(); + printf("foo.c\n"); +} +""") + +test.run(chdir="test2") + +_obj = TestSCons._obj + +test.must_not_exist(test.workpath('test2', 'foo' + _obj)) +test.must_not_exist(test.workpath('test2', 'bar' + _obj)) +test.must_exist(test.workpath('test2', 'Build', 'foo' + _obj)) +test.must_exist(test.workpath('test2', 'Build', 'bar' + _obj)) + +################### +# Make sure that directories for subsidiary SConscript() calls +# in a variant_dir get created if they don't already exist. +test.subdir('test3') + +test.subdir(['test3', 'src'], ['test3', 'src', '_glscry']) + +test.write(['test3', 'SConstruct'], """\ +SConscript(dirs=['src'], variant_dir='build', duplicate=0) +""") + +test.write(['test3', 'src', 'SConscript'], """\ +SConscript(dirs=['_glscry']) +""") + +test.write(['test3', 'src', '_glscry', 'SConscript'], """\ +""") + +test.write(['test3', 'src', 'file.in'], "file.in\n") + +test.write(['test3', 'src', '_glscry', 'file.in'], "file.in\n") + +test.run(chdir='test3') + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/VariantDir/VariantDir.py b/test/VariantDir/VariantDir.py new file mode 100644 index 0000000..0092692 --- /dev/null +++ b/test/VariantDir/VariantDir.py @@ -0,0 +1,407 @@ +#!/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__" + +import TestSCons + +_exe = TestSCons._exe + +test = TestSCons.TestSCons() +fortran_runtime = test.gccFortranLibs() + +fortran = test.detect('FORTRAN') + +foo11 = test.workpath('work1', 'build', 'var1', 'foo1' + _exe) +foo12 = test.workpath('work1', 'build', 'var1', 'foo2' + _exe) +foo21 = test.workpath('work1', 'build', 'var2', 'foo1' + _exe) +foo22 = test.workpath('work1', 'build', 'var2', 'foo2' + _exe) +foo31 = test.workpath('work1', 'build', 'var3', 'foo1' + _exe) +foo32 = test.workpath('work1', 'build', 'var3', 'foo2' + _exe) +foo41 = test.workpath('work1', 'build', 'var4', 'foo1' + _exe) +foo42 = test.workpath('work1', 'build', 'var4', 'foo2' + _exe) +foo51 = test.workpath('build', 'var5', 'foo1' + _exe) +foo52 = test.workpath('build', 'var5', 'foo2' + _exe) + +bar11 = test.workpath('work1', 'build', 'var1', 'bar1' + _exe) +bar12 = test.workpath('work1', 'build', 'var1', 'bar2' + _exe) +bar21 = test.workpath('work1', 'build', 'var2', 'bar1' + _exe) +bar22 = test.workpath('work1', 'build', 'var2', 'bar2' + _exe) +bar31 = test.workpath('work1', 'build', 'var3', 'bar1' + _exe) +bar32 = test.workpath('work1', 'build', 'var3', 'bar2' + _exe) +bar41 = test.workpath('work1', 'build', 'var4', 'bar1' + _exe) +bar42 = test.workpath('work1', 'build', 'var4', 'bar2' + _exe) +bar51 = test.workpath('build', 'var5', 'bar1' + _exe) +bar52 = test.workpath('build', 'var5', 'bar2' + _exe) + +test.subdir('work1', 'work2', 'work3') + +test.write(['work1', 'SConstruct'], """ +src = Dir('src') +var2 = Dir('build/var2') +var3 = Dir('build/var3') +var4 = Dir('build/var4') +var5 = Dir('../build/var5') +var6 = Dir('../build/var6') + +env = Environment(BUILD = 'build', SRC = 'src') + +VariantDir('build/var1', src) +VariantDir(var2, src) +VariantDir(var3, src, duplicate=0) +env.VariantDir("$BUILD/var4", "$SRC", duplicate=0) +VariantDir(var5, src, duplicate=0) +VariantDir(var6, src) + +env = Environment(CPPPATH='#src', FORTRANPATH='#src') +SConscript('build/var1/SConscript', "env") +SConscript('build/var2/SConscript', "env") + +env = Environment(CPPPATH=src, FORTRANPATH=src) +SConscript('build/var3/SConscript', "env") +SConscript(File('SConscript', var4), "env") + +env = Environment(CPPPATH='.', FORTRANPATH='.') +SConscript('../build/var5/SConscript', "env") +SConscript('../build/var6/SConscript', "env") +""") + +test.subdir(['work1', 'src']) +test.write(['work1', 'src', 'SConscript'], """ +import os.path + +def buildIt(target, source, env): + if not os.path.exists('build'): + os.mkdir('build') + f1=open(str(source[0]), 'r') + f2=open(str(target[0]), 'w') + f2.write(f1.read()) + f2.close() + f1.close() + return 0 +Import("env") +env.Command(target='f2.c', source='f2.in', action=buildIt) +env.Program(target='foo2', source='f2.c') +env.Program(target='foo1', source='f1.c') +env.Command(target='f3.h', source='f3h.in', action=buildIt) +env.Command(target='f4.h', source='f4h.in', action=buildIt) +env.Command(target='f4.c', source='f4.in', action=buildIt) + +env2=env.Clone(CPPPATH='.') +env2.Program(target='foo3', source='f3.c') +env2.Program(target='foo4', source='f4.c') + +try: + fortran = env.subst('$FORTRAN') +except: + fortran = None + +if fortran and env.Detect(fortran): + env.Command(target='b2.f', source='b2.in', action=buildIt) + env.Clone(LIBS = %s).Program(target='bar2', source='b2.f') + env.Clone(LIBS = %s).Program(target='bar1', source='b1.f') +""" % (fortran_runtime, fortran_runtime)) + +test.write(['work1', 'src', 'f1.c'], r""" +#include <stdio.h> +#include <stdlib.h> + +#include "f1.h" + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf(F1_STR); + exit (0); +} +""") + +test.write(['work1', 'src', 'f2.in'], r""" +#include <stdio.h> +#include <stdlib.h> + +#include "f2.h" + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf(F2_STR); + exit (0); +} +""") + +test.write(['work1', 'src', 'f3.c'], r""" +#include <stdio.h> +#include <stdlib.h> + +#include "f3.h" + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf(F3_STR); + exit (0); +} +""") + +test.write(['work1', 'src', 'f4.in'], r""" +#include <stdio.h> +#include <stdlib.h> + +#include "f4.h" + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf(F4_STR); + exit (0); +} +""") + +test.write(['work1', 'src', 'f1.h'], r""" +#define F1_STR "f1.c\n" +""") + +test.write(['work1', 'src', 'f2.h'], r""" +#define F2_STR "f2.c\n" +""") + +test.write(['work1', 'src', 'f3h.in'], r""" +#define F3_STR "f3.c\n" +""") + +test.write(['work1', 'src', 'f4h.in'], r""" +#define F4_STR "f4.c\n" +""") + +test.write(['work1', 'src', 'b1.f'], r""" + PROGRAM FOO + INCLUDE 'b1.for' + STOP + END +""") + +test.write(['work1', 'src', 'b2.in'], r""" + PROGRAM FOO + INCLUDE 'b2.for' + STOP + END +""") + +test.write(['work1', 'src', 'b1.for'], r""" + PRINT *, 'b1.for' +""") + +test.write(['work1', 'src', 'b2.for'], r""" + PRINT *, 'b2.for' +""") + +# Some releases of freeBSD seem to have library complaints about +# tempnam(). Filter out these annoying messages before checking for +# error output. +def blank_output(err): + if not err: + return 1 + stderrlines = [l for l in err.split('\n') if l] + msg = "warning: tempnam() possibly used unsafely" + stderrlines = [l for l in stderrlines if l.find(msg) == -1] + return len(stderrlines) == 0 + +test.run(chdir='work1', arguments = '. ../build', stderr=None) + +test.fail_test(not blank_output(test.stderr())) + +test.run(program = foo11, stdout = "f1.c\n") +test.run(program = foo12, stdout = "f2.c\n") +test.run(program = foo21, stdout = "f1.c\n") +test.run(program = foo22, stdout = "f2.c\n") +test.run(program = foo31, stdout = "f1.c\n") +test.run(program = foo32, stdout = "f2.c\n") +test.run(program = foo41, stdout = "f1.c\n") +test.run(program = foo42, stdout = "f2.c\n") +test.run(program = foo51, stdout = "f1.c\n") +test.run(program = foo52, stdout = "f2.c\n") + +if fortran: + test.run(program = bar11, stdout = " b1.for\n") + test.run(program = bar12, stdout = " b2.for\n") + test.run(program = bar21, stdout = " b1.for\n") + test.run(program = bar22, stdout = " b2.for\n") + test.run(program = bar31, stdout = " b1.for\n") + test.run(program = bar32, stdout = " b2.for\n") + test.run(program = bar41, stdout = " b1.for\n") + test.run(program = bar42, stdout = " b2.for\n") + test.run(program = bar51, stdout = " b1.for\n") + test.run(program = bar52, stdout = " b2.for\n") + +test.run(chdir='work1', arguments='. ../build', stdout=test.wrap_stdout("""\ +scons: `.' is up to date. +scons: `%s' is up to date. +""" % test.workpath('build'))) + +import os +import stat +def equal_stats(x,y): + x = os.stat(x) + y = os.stat(y) + return (stat.S_IMODE(x[stat.ST_MODE]) == stat.S_IMODE(y[stat.ST_MODE]) and + x[stat.ST_MTIME] == y[stat.ST_MTIME]) + +# Make sure we did duplicate the source files in build/var2, +# and that their stats are the same: +test.must_exist(['work1', 'build', 'var2', 'f1.c']) +test.must_exist(['work1', 'build', 'var2', 'f2.in']) +test.fail_test(not equal_stats(test.workpath('work1', 'build', 'var2', 'f1.c'), test.workpath('work1', 'src', 'f1.c'))) +test.fail_test(not equal_stats(test.workpath('work1', 'build', 'var2', 'f2.in'), test.workpath('work1', 'src', 'f2.in'))) + +# Make sure we didn't duplicate the source files in build/var3. +test.must_not_exist(['work1', 'build', 'var3', 'f1.c']) +test.must_not_exist(['work1', 'build', 'var3', 'f2.in']) +test.must_not_exist(['work1', 'build', 'var3', 'b1.f']) +test.must_not_exist(['work1', 'build', 'var3', 'b2.in']) + +# Make sure we didn't duplicate the source files in build/var4. +test.must_not_exist(['work1', 'build', 'var4', 'f1.c']) +test.must_not_exist(['work1', 'build', 'var4', 'f2.in']) +test.must_not_exist(['work1', 'build', 'var4', 'b1.f']) +test.must_not_exist(['work1', 'build', 'var4', 'b2.in']) + +# Make sure we didn't duplicate the source files in build/var5. +test.must_not_exist(['build', 'var5', 'f1.c']) +test.must_not_exist(['build', 'var5', 'f2.in']) +test.must_not_exist(['build', 'var5', 'b1.f']) +test.must_not_exist(['build', 'var5', 'b2.in']) + +# verify that header files in the source directory are scanned properly: +test.write(['work1', 'src', 'f1.h'], r""" +#define F1_STR "f1.c 2\n" +""") + +test.write(['work1', 'src', 'f3h.in'], r""" +#define F3_STR "f3.c 2\n" +""") + +test.write(['work1', 'src', 'f4h.in'], r""" +#define F4_STR "f4.c 2\n" +""") + +test.run(chdir='work1', arguments = '../build/var5', stderr=None) + +test.fail_test(not blank_output(test.stderr())) + +test.run(program = foo51, stdout = "f1.c 2\n") +test.run(program = test.workpath('build', 'var5', 'foo3' + _exe), + stdout = "f3.c 2\n") +test.run(program = test.workpath('build', 'var5', 'foo4' + _exe), + stdout = "f4.c 2\n") + +test.run(chdir='work1', arguments='../build/var5', stdout=test.wrap_stdout("""\ +scons: `%s' is up to date. +""" % test.workpath('build', 'var5'))) + +# +test.write(['work2', 'SConstruct'], """\ +env = Environment() +env.Program('prog.c') +""") + +test.write(['work2', 'prog.c'], r""" +#include <stdio.h> +#include <stdlib.h> + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("work2/prog.c\n"); + exit (0); +} +""") + +test.run(chdir='work2', arguments='.') + +test.up_to_date(chdir='work2', arguments='.') + +# +test.write(['work2', 'SConstruct'], """\ +env = Environment() +VariantDir('build', '.') +Export('env') +SConscript('build/SConscript') +""") + +test.write(['work2', 'SConscript'], """\ +Import('env') +env.Program('prog.c') +""") + +test.run(chdir='work2', arguments='.', stderr=None) + +test.fail_test(not blank_output(test.stderr())) + +test.run(chdir='work2', arguments='.', + stdout=test.wrap_stdout("""\ +scons: building associated VariantDir targets: build +scons: `.' is up to date. +""")) + +test.write( ['work3', 'SConstruct'], """\ +SConscriptChdir(0) +VariantDir('build', '.', duplicate=1 ) +SConscript( 'build/SConscript' ) +""") + +test.write( ['work3', 'SConscript'], """\ +import sys +headers = ['existing.h', 'non_existing.h'] +for header in headers: + h = File( header ) + contents = h.get_contents() + sys.stderr.write( '%s:%s\\n' % (header, contents)) +""") + +test.write( ['work3', 'existing.h'], """\ +/* a header file */\ +""") + +test.run(chdir='work3', + stdout=test.wrap_stdout("""\ +scons: building associated VariantDir targets: build +scons: `.' is up to date. +"""), + stderr="""\ +existing.h:/* a header file */ +non_existing.h: +""") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/VariantDir/errors.py b/test/VariantDir/errors.py new file mode 100644 index 0000000..d1490d4 --- /dev/null +++ b/test/VariantDir/errors.py @@ -0,0 +1,178 @@ +#!/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__" + +""" +Validate successful handling of errors when duplicating things in +VariantDirs. This is generally when the VariantDir, or something in it, +is read-only. +""" + +import os +import stat +import sys +import TestSCons + +test = TestSCons.TestSCons() + +for dir in ['normal', 'ro-dir', 'ro-SConscript', 'ro-src']: + test.subdir(dir, [dir, 'src']) + + test.write([dir, 'SConstruct'], """\ +import os.path +VariantDir('build', 'src') +SConscript(os.path.join('build', 'SConscript')) +""") + + test.write([dir, 'src', 'SConscript'], """\ +def fake_scan(node, env, target): + # We fetch the contents here, even though we don't examine + # them, because get_contents() will cause the engine to + # try to link the source file into the build directory, + # potentially triggering a different failure case. + contents = node.get_contents() + return [] + +def cat(env, source, target): + target = str(target[0]) + f = open(target, "wb") + for src in source: + f.write(open(str(src), "rb").read()) + f.close() + +env = Environment(BUILDERS={'Build':Builder(action=cat)}, + SCANNERS=[Scanner(fake_scan, skeys = ['.in'])]) + +# Do some Node test operations to ensure no side-effects cause failures +File('file.in').exists() +File('file.in').is_derived() + +env.Build('file.out', 'file.in') +""") + + test.write([dir, 'src', 'file.in'], dir + "/src/file.in\n") + +# Just verify that the normal case works fine. +test.run(chdir = 'normal', arguments = ".") + +test.fail_test(test.read(['normal', 'build', 'file.out']) != "normal/src/file.in\n") + +# Verify the error when the VariantDir itself is read-only. Don't bother +# to test this on Windows, because the ACL (I think) still allows the +# owner to create files in the directory even when it's read-only. +if sys.platform != 'win32': + dir = os.path.join('ro-dir', 'build') + test.subdir(dir) + os.chmod(dir, os.stat(dir)[stat.ST_MODE] & ~stat.S_IWUSR) + + test.run(chdir = 'ro-dir', + arguments = ".", + status = 2, + stderr = "scons: *** Cannot duplicate `%s' in `build': Permission denied. Stop.\n" % os.path.join('src', 'SConscript')) + +# Verify the error when the SConscript file within the VariantDir is +# read-only. Note that we have to make the directory read-only too, +# because otherwise our duplication logic will be able to unlink +# the read-only SConscript and duplicate the new one. +dir = os.path.join('ro-SConscript', 'build') +test.subdir(dir) +SConscript = test.workpath(dir, 'SConscript') +test.write(SConscript, '') +os.chmod(SConscript, os.stat(SConscript)[stat.ST_MODE] & ~stat.S_IWUSR) +f = open(SConscript, 'r') +os.chmod(dir, os.stat(dir)[stat.ST_MODE] & ~stat.S_IWUSR) + +test.run(chdir = 'ro-SConscript', + arguments = ".", + status = 2, + stderr = "scons: *** Cannot duplicate `%s' in `build': Permission denied. Stop.\n" % os.path.join('src', 'SConscript')) + +os.chmod('ro-SConscript', os.stat('ro-SConscript')[stat.ST_MODE] | stat.S_IWUSR) +f.close() + +test.run(chdir = 'ro-SConscript', + arguments = ".", + status = 2, + stderr = "scons: *** Cannot duplicate `%s' in `build': Permission denied. Stop.\n" % os.path.join('src', 'SConscript')) + +# Verify the error when the source file within the VariantDir is +# read-only. Note that we have to make the directory read-only too, +# because otherwise our duplication logic will be able to unlink the +# read-only source file and duplicate the new one. But because we've +# made the VariantDir read-only, we must also create a writable SConscript +# file there so it can be duplicated from the source directory. +dir = os.path.join('ro-src', 'build') +test.subdir(dir) +test.write([dir, 'SConscript'], '') +file_in = test.workpath(dir, 'file.in') +test.write(file_in, '') +os.chmod(file_in, os.stat(file_in)[stat.ST_MODE] & ~stat.S_IWUSR) +f = open(file_in, 'r') +os.chmod(dir, os.stat(dir)[stat.ST_MODE] & ~stat.S_IWUSR) + +test.run(chdir = 'ro-src', + arguments = ".", + status = 2, + stderr = """\ +scons: *** Cannot duplicate `%s' in `build': Permission denied. Stop. +""" % (os.path.join('src', 'file.in'))) + +test.run(chdir = 'ro-src', + arguments = "-k .", + status = 2, + stderr = """\ +scons: *** Cannot duplicate `%s' in `build': Permission denied. Stop. +""" % (os.path.join('src', 'file.in'))) + +f.close() + +# ensure that specifying multiple source directories for one +# build directory results in an error message, rather +# than just silently failing. +test.subdir('duplicate', ['duplicate', 'src1'], ['duplicate', 'src2']) + +duplicate_SConstruct_path = test.workpath('duplicate', 'SConstruct') + +test.write(duplicate_SConstruct_path, """\ +VariantDir('build', 'src1') +VariantDir('build', 'src2') +""") + +expect_stderr = """ +scons: *** 'build' already has a source directory: 'src1'. +""" + test.python_file_line(duplicate_SConstruct_path, 2) + +test.run(chdir = 'duplicate', + arguments = ".", + status = 2, + stderr = expect_stderr) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/VariantDir/guess-subdir.py b/test/VariantDir/guess-subdir.py new file mode 100644 index 0000000..294253b --- /dev/null +++ b/test/VariantDir/guess-subdir.py @@ -0,0 +1,75 @@ +#!/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 that the logic that "guesses" the associated VariantDir for a +subdirectory correctly builds targets in the VariantDir subdirectory. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir(['work'], ['work', 'src']) + +test.write(['work', 'SConstruct'], """ +c_builddir = r'%s' +VariantDir(c_builddir, '.', duplicate=0) +SConscript(c_builddir + '/SConscript') +""" % test.workpath('debug')) + +test.write(['work', 'SConscript'], """ +SConscript('src/SConscript') +""") + +test.write(['work', 'src', 'SConscript'], """ +env = Environment(OBJSUFFIX='.obj', + PROGSUFFIX='.exe') +env.Program('test.cpp') +""") + +test.write(['work', 'src', 'test.cpp'], """\ +#include <stdio.h> +#include <stdlib.h> +int +main(int argc, char *argv[]) +{ + printf("work/src/test.cpp\\n"); +} +""") + +test.run(chdir = 'work', arguments = '.') + +test.must_exist(test.workpath('debug', 'src', 'test.obj')) +test.must_exist(test.workpath('debug', 'src', 'test.exe')) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/VariantDir/include-subdir.py b/test/VariantDir/include-subdir.py new file mode 100644 index 0000000..d616bba --- /dev/null +++ b/test/VariantDir/include-subdir.py @@ -0,0 +1,82 @@ +#!/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 VariantDir handling of #include files in subdirectories. + +When a source file #includes a file that is not in the current directory, +we have to make sure that the file gets copied to the variant dir. (This +was not the case for 0.98.5 and earlier) + +Test case supplied by Jared Grubb, based on a minimal example supplied +by Ali Tofigh, filed as http://scons.tigris.org/issues/show_bug.cgi?id=2121 +""" + +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.subdir('src/utils') +test.write(['src', 'main.cpp'], """\ +#include "main.h" +#include "utils/util.h" + +int main(int argc, char* argv[]) +{ + return MAIN_VALUE+UTIL_VALUE; +} +""") + +test.write(['src', 'main.h'], """\ +#define MAIN_VALUE 2 +""") + +test.write(['src', 'utils', 'util.h'], """\ +#define UTIL_VALUE -2 +""") + +test.write('SConstruct', """ +env = Environment() +env.VariantDir('bin', 'src') +o = env.Object('bin/main', 'bin/main.cpp') +env.Program('bin/main', o) +""") + +test.run(arguments = '.') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/VariantDir/nested-sconscripts.py b/test/VariantDir/nested-sconscripts.py new file mode 100644 index 0000000..8782e41 --- /dev/null +++ b/test/VariantDir/nested-sconscripts.py @@ -0,0 +1,70 @@ +#!/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 that nested SConscript files in a VariantDir don't throw +an OSError exception looking for the wrong file. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir(['src'], + ['src', 'md'], + ['src', 'md', 'test']) + +test.write(['src', 'SConstruct'], """\ +BUILD_DIR = '../build' + +base_env = Environment() + +for flavor in ['prod', 'debug']: + build_env = base_env.Clone() + # In real life, we would modify build_env appropriately here + FLAVOR_DIR = BUILD_DIR + '/' + flavor + Export('build_env') + VariantDir(FLAVOR_DIR, 'md', duplicate=0) + SConscript(FLAVOR_DIR + '/SConscript') +""") + +test.write(['src', 'md', 'SConscript'], """\ +SConscript('test/SConscript') +""") + +test.write(['src', 'md', 'test', 'SConscript'], """\ +# empty +""") + +test.run(chdir='src') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/VariantDir/no-execute.py b/test/VariantDir/no-execute.py new file mode 100644 index 0000000..022bf7e --- /dev/null +++ b/test/VariantDir/no-execute.py @@ -0,0 +1,97 @@ + +#!/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__" + +""" +Verify that use of a VariantDir works when the -n option is used (and +the VariantDir, therefore, isn't actually created) when both duplicate=0 +and duplicate=1 are used. +""" + +import os + +import TestSCons + +test = TestSCons.TestSCons() + +a_file_in = os.path.join('a', 'file.in') +build0_a_file_out = os.path.join('build0', 'a', 'file.out') +build1_file_out = os.path.join('build1', 'file.out') +build1_file_in = os.path.join('build1', 'file.in') + +test.subdir('a') + +test.write('SConstruct', """\ +env = Environment() +Export('env') +env.SConscript('SConscript', + exported=['env'], + variant_dir='build0', + duplicate=0) +env.SConscript('a/SConscript', + exported=['env'], + variant_dir='build1', + duplicate=1) +""") + +test.write('SConscript', """\ +Import(['env']) +env.SConscript('a/SConscript', exports=['env'], duplicate=0) +""") + +test.write(['a', 'SConscript'], """\ +Import(['env']) +env.Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE')) +""") + +test.write(['a', 'file.in'], "a/file.in\n") + +expect = """\ +scons: building associated VariantDir targets: build0 +Copy("%(build0_a_file_out)s", "%(a_file_in)s") +Copy("%(build1_file_out)s", "%(build1_file_in)s") +""" % locals() + +test.run(arguments = '-Q -n', stdout=expect) + +test.must_not_exist('build0') +test.must_not_exist('build1') + +# Sanity check that the right thing happens when we *do* build it, just +# to make sure that the expected -n behavior above isn't a side effect +# of doing something wrong without -n. +test.run() + +test.must_match(['build0', 'a', 'file.out'], "a/file.in\n") +test.must_match(['build1', 'file.out'], "a/file.in\n") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/VariantDir/reflect.py b/test/VariantDir/reflect.py new file mode 100644 index 0000000..ea5689a --- /dev/null +++ b/test/VariantDir/reflect.py @@ -0,0 +1,142 @@ +#!/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__" + +""" +This test validates the correct operation of a VariantDir specification +in avoiding reflection: reflection is the case where the variant_dir is +located under the corresponding source dir, and trying to use elements +in the variant_dir as sources for that same build dir. + +Test based on bug #1055521 filed by Gary Oberbrunner. +""" + +import os.path +import re + +import TestSCons + +test = TestSCons.TestSCons() + +_python_ = TestSCons._python_ +re_python = re.escape(TestSCons._python_) + +test.write("mycc.py", """ +print 'Compile' +""") + +test.write("mylink.py", """ +print 'Link' +""") + +sconstruct = """ +env = Environment(CC = r'%(_python_)s mycc.py', + LINK = r'%(_python_)s mylink.py', + INCPREFIX = 'INC_', + INCSUFFIX = '_CNI', + CPPPATH='%(cpppath)s') # note no leading '#' +Export("env") +SConscript('SConscript', variant_dir="dir1/dir2", src_dir=".") +""" + +test.write('SConscript', """\ +Import("env") +env.Program("foo", "src1/foo.c") +Default(".") +""") + +test.write('foo.h', '#define HI_STR "hello, there!"\n') + +test.subdir('src1') + +test.write(['src1', 'foo.c'], """\ +#include <stdio.h> +#include "foo.h" +main() { printf(HI_STR);} +""") + +# Test the bad cpppath; make sure it doesn't reflect dir1/dir2/foo.h +# into dir1/dir2/dir1/dir2/foo.h, and make sure the target/message for +# builds is correct. + +cpppath = 'dir1/dir2' # note, no leading '#' +test.write('SConstruct', sconstruct % locals() ) + +targets = re.escape(os.path.join('dir1', 'dir2')) +INC_CNI = re.escape(os.path.join('INC_dir1', 'dir2', 'dir1', 'dir2_CNI')) + +# The .+ after mycc\\.py below handles /nologo flags from Visual C/C++. +expect = test.wrap_stdout("""\ +scons: building associated VariantDir targets: %(targets)s +%(re_python)s mycc\\.py.* %(INC_CNI)s.* +Compile +%(re_python)s mylink\\.py .+ +Link +""" % locals()) + +test.run(arguments = '', match=TestSCons.match_re, stdout=expect) + +# Note that we don't check for the existence of dir1/dir2/foo.h, because +# this bad cpppath will expand to dir1/dir2/dir1/dir2, which means it +# won't pick up the srcdir copy of dir/dir2/foo.h. That's all right, +# we just need to make sure it doesn't create dir1/dir2/dir1/dir2/foo.h. +test.must_exist(['dir1', 'dir2', 'src1', 'foo.c']) +test.must_not_exist(['dir1', 'dir2', 'dir1', 'dir2', 'foo.h']) + +import shutil +shutil.rmtree('dir1', ignore_errors=1) +test.must_not_exist('dir1') + +# Now test the good cpppath and make sure everything looks right. + +cpppath = '#dir1/dir2' # note leading '#' +test.write('SConstruct', sconstruct % locals() ) + +INC_CNI = re.escape(os.path.join('INC_dir1', 'dir2_CNI')) + +# The .* after mycc\\.py below handles /nologo flags from Visual C/C++. +test.run(arguments = '', + stdout=test.wrap_stdout("""\ +scons: building associated VariantDir targets: %(targets)s +%(re_python)s mycc\\.py.* %(INC_CNI)s.* +Compile +%(re_python)s mylink\\.py .+ +Link +""" % locals()), + match=TestSCons.match_re, + ) + +test.must_exist(['dir1', 'dir2', 'foo.h']) +test.must_exist(['dir1', 'dir2', 'src1', 'foo.c']) +test.must_not_exist(['dir1', 'dir2', 'dir1', 'dir2', 'foo.h']) + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/VariantDir/removed-files.py b/test/VariantDir/removed-files.py new file mode 100644 index 0000000..113f667 --- /dev/null +++ b/test/VariantDir/removed-files.py @@ -0,0 +1,105 @@ +#!/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 VariantDir 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.VariantDir('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() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/VariantDir/under.py b/test/VariantDir/under.py new file mode 100644 index 0000000..2508db5 --- /dev/null +++ b/test/VariantDir/under.py @@ -0,0 +1,100 @@ +#!/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 various combinations of variant_dir when the source directory is, +or is not, underneath the SConstruct directory. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.subdir('work', ['work', 'sub'], 'other') + +test.write(['work', 'SConscript'], """\ +f = Command("file.out", "file.in", Copy("$TARGET", "$SOURCE")) +Default(f) +""") + +test.write(['work', 'file.in'], "work/file.in\n") + + + +test.write(['work', 'sub', 'SConstruct'], """\ +SConscript('../SConscript', variant_dir='build1') +""") + +test.run(chdir='work/sub') + +test.must_match(['work', 'sub', 'build1', 'file.out'], "work/file.in\n") + + + +test.write(['work', 'sub', 'SConstruct'], """ +SConscript('../SConscript', variant_dir='../build2') +""") + +test.run(chdir='work/sub') + +test.must_match(['work', 'build2', 'file.out'], "work/file.in\n") + + + +test.write(['work', 'sub', 'SConstruct'], """ +SConscript('../SConscript', variant_dir='../../build3') +""") + +test.run(chdir='work/sub') + +test.must_match(['build3', 'file.out'], "work/file.in\n") + + + +test.write(['work', 'SConstruct'], """ +SConscript('../other/SConscript', variant_dir='build4') +""") + +test.write(['other', 'SConscript'], """\ +f = Command("file.out", "file.in", Copy("$TARGET", "$SOURCE")) +Default(f) +""") + +test.write(['other', 'file.in'], "other/file.in\n") + +test.run(chdir='work') + +test.must_match(['work', 'build4', 'file.out'], "other/file.in\n") + + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: |
