From 2db3a7a6aaec21e692ffc4604d5ddda383191845 Mon Sep 17 00:00:00 2001 From: stevenknight Date: Tue, 3 Dec 2002 14:42:35 +0000 Subject: [PATCH] Support variable substitution on scanner directories. (Charles Crain) git-svn-id: http://scons.tigris.org/svn/scons/trunk@512 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- src/CHANGES.txt | 3 +++ src/engine/SCons/Node/FS.py | 2 +- src/engine/SCons/Scanner/C.py | 2 +- src/engine/SCons/Scanner/CTests.py | 15 ++++++++++++++ src/engine/SCons/Scanner/Fortran.py | 2 +- src/engine/SCons/Scanner/FortranTests.py | 18 ++++++++++++++++ src/engine/SCons/Scanner/Prog.py | 3 +-- src/engine/SCons/Scanner/ProgTests.py | 15 ++++++++++++++ src/engine/SCons/Util.py | 26 ++++++++++++++---------- src/engine/SCons/UtilTests.py | 21 +++++++++++++++++++ test/CPPPATH.py | 3 ++- test/F77PATH.py | 2 +- test/LIBPATH.py | 3 ++- 13 files changed, 96 insertions(+), 19 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 586f81a2..a2c6d36c 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -15,6 +15,9 @@ RELEASE 0.09 - - Add a Prepend() method to Environments, to append values to the beginning of construction variables. + - Add support for construction variable substition on scanner + directories (in CPPPATH, F77PATH, LIBPATH, etc.). + From Charles Crain and Steven Knight: - Add Repository() functionality, including the -Y option. diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index b805d4a5..9976ef25 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -362,7 +362,7 @@ class FS: then the same applies. """ self.__setTopLevelDir() - if name[0] == '#': + if name and name[0] == '#': directory = self.Top name = name[1:] if name and (name[0] == os.sep or name[0] == '/'): diff --git a/src/engine/SCons/Scanner/C.py b/src/engine/SCons/Scanner/C.py index 6eb03f4b..6e7db584 100644 --- a/src/engine/SCons/Scanner/C.py +++ b/src/engine/SCons/Scanner/C.py @@ -80,7 +80,7 @@ def scan(node, env, target, fs = SCons.Node.FS.default_fs): if not hasattr(target, 'cpppath'): try: - target.cpppath = tuple(fs.Rsearchall(SCons.Util.mapPaths(env['CPPPATH'], target.cwd), clazz=SCons.Node.FS.Dir, must_exist=0)) + target.cpppath = tuple(fs.Rsearchall(SCons.Util.mapPaths(env['CPPPATH'], target.cwd, env), clazz=SCons.Node.FS.Dir, must_exist=0)) except KeyError: target.cpppath = () diff --git a/src/engine/SCons/Scanner/CTests.py b/src/engine/SCons/Scanner/CTests.py index be911d9e..28a5f520 100644 --- a/src/engine/SCons/Scanner/CTests.py +++ b/src/engine/SCons/Scanner/CTests.py @@ -175,6 +175,9 @@ class DummyEnvironment: else: raise KeyError, "Dummy environment only has CPPPATH attribute." + def subst(self, arg): + return arg + def __getitem__(self,key): return self.Dictionary()[key] @@ -349,6 +352,17 @@ class CScannerTestCase12(unittest.TestCase): deps4 = s.scan(fs.File('build2/ccc.c'), env, DummyTarget()) deps_match(self, deps4, [ test.workpath('repository/src/ddd.h') ]) os.chdir(test.workpath('')) + +class CScannerTestCase13(unittest.TestCase): + def runTest(self): + class SubstEnvironment(DummyEnvironment): + def subst(self, arg, test=test): + return test.workpath("d1") + env = SubstEnvironment(["blah"]) + s = SCons.Scanner.C.CScan() + deps = s.scan(make_node('f1.cpp'), env, DummyTarget()) + headers = ['d1/f2.h', 'f1.h'] + deps_match(self, deps, map(test.workpath, headers)) def suite(): @@ -364,6 +378,7 @@ def suite(): suite.addTest(CScannerTestCase10()) suite.addTest(CScannerTestCase11()) suite.addTest(CScannerTestCase12()) + suite.addTest(CScannerTestCase13()) return suite if __name__ == "__main__": diff --git a/src/engine/SCons/Scanner/Fortran.py b/src/engine/SCons/Scanner/Fortran.py index afe46d09..5d908f71 100644 --- a/src/engine/SCons/Scanner/Fortran.py +++ b/src/engine/SCons/Scanner/Fortran.py @@ -78,7 +78,7 @@ def scan(node, env, target, fs = SCons.Node.FS.default_fs): if not hasattr(target, 'f77path'): try: - target.f77path = tuple(fs.Rsearchall(SCons.Util.mapPaths(env['F77PATH'], target.cwd), clazz=SCons.Node.FS.Dir, must_exist=0)) + target.f77path = tuple(fs.Rsearchall(SCons.Util.mapPaths(env['F77PATH'], target.cwd, env), clazz=SCons.Node.FS.Dir, must_exist=0)) except KeyError: target.f77path = () diff --git a/src/engine/SCons/Scanner/FortranTests.py b/src/engine/SCons/Scanner/FortranTests.py index 3e3f7da6..e2cfcd6d 100644 --- a/src/engine/SCons/Scanner/FortranTests.py +++ b/src/engine/SCons/Scanner/FortranTests.py @@ -152,6 +152,9 @@ class DummyEnvironment: def __delitem__(self,key): del self.Dictionary()[key] + def subst(self, arg): + return arg + def deps_match(self, deps, headers): scanned = map(os.path.normpath, map(str, deps)) expect = map(os.path.normpath, headers) @@ -354,6 +357,20 @@ class FortranScannerTestCase14(unittest.TestCase): deps_match(self, deps4, [ test.workpath('repository/src/ddd.f') ]) os.chdir(test.workpath('')) +class FortranScannerTestCase15(unittest.TestCase): + def runTest(self): + class SubstEnvironment(DummyEnvironment): + def subst(self, arg, test=test): + return test.workpath("d1") + test.write(['d1', 'f2.f'], " INCLUDE 'fi.f'\n") + env = SubstEnvironment(["junk"]) + s = SCons.Scanner.Fortran.FortranScan() + fs = SCons.Node.FS.FS(original) + deps = s.scan(make_node('fff1.f', fs), env, DummyTarget()) + headers = ['d1/f1.f', 'd1/f2.f'] + deps_match(self, deps, map(test.workpath, headers)) + test.write(['d1', 'f2.f'], "\n") + def suite(): suite = unittest.TestSuite() suite.addTest(FortranScannerTestCase1()) @@ -370,6 +387,7 @@ def suite(): suite.addTest(FortranScannerTestCase12()) suite.addTest(FortranScannerTestCase13()) suite.addTest(FortranScannerTestCase14()) + suite.addTest(FortranScannerTestCase15()) return suite if __name__ == "__main__": diff --git a/src/engine/SCons/Scanner/Prog.py b/src/engine/SCons/Scanner/Prog.py index 818aa865..7cfd9f41 100644 --- a/src/engine/SCons/Scanner/Prog.py +++ b/src/engine/SCons/Scanner/Prog.py @@ -49,9 +49,8 @@ def scan(node, env, target, fs): # target.libpath - env['LIBPATH'] converted to nodes if not hasattr(target, 'libpath'): - def Dir(x, dir=target.cwd, fs=fs): return fs.Dir(x,dir) try: - target.libpath = tuple(SCons.Node.arg2nodes(env['LIBPATH'],Dir)) + target.libpath = tuple(fs.Rsearchall(SCons.Util.mapPaths(env['LIBPATH'], target.cwd, env), clazz=SCons.Node.FS.Dir, must_exist=0)) except KeyError: target.libpath = () diff --git a/src/engine/SCons/Scanner/ProgTests.py b/src/engine/SCons/Scanner/ProgTests.py index 4e60ccfa..1302e467 100644 --- a/src/engine/SCons/Scanner/ProgTests.py +++ b/src/engine/SCons/Scanner/ProgTests.py @@ -107,11 +107,26 @@ class ProgScanTestCase3(unittest.TestCase): deps = s.scan('dummy', env, DummyTarget()) assert deps_match(deps, ['d1/l2.lib', 'd1/d2/l3.lib']), map(str, deps) +class ProgScanTestCase5(unittest.TestCase): + def runTest(self): + class SubstEnvironment(DummyEnvironment): + def subst(self, arg, path=test.workpath("d1")): + if arg == "blah": + return test.workpath("d1") + else: + return arg + env = SubstEnvironment(LIBPATH=[ "blah" ], + LIBS=string.split('l2 l3')) + s = SCons.Scanner.Prog.ProgScan() + deps = s.scan('dummy', env, DummyTarget()) + assert deps_match(deps, [ 'd1/l2.lib' ]), map(str, deps) + def suite(): suite = unittest.TestSuite() suite.addTest(ProgScanTestCase1()) suite.addTest(ProgScanTestCase2()) suite.addTest(ProgScanTestCase3()) + suite.addTest(ProgScanTestCase5()) if hasattr(types, 'UnicodeType'): code = """if 1: class ProgScanTestCase4(unittest.TestCase): diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 62772ae1..17b28827 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -518,7 +518,7 @@ def Split(arg): else: return [arg] -def mapPaths(paths, dir): +def mapPaths(paths, dir, env=None): """Takes a single node or string, or a list of nodes and/or strings. We leave the nodes untouched, but we put the strings under the supplied directory node dir, if they are not an absolute @@ -528,27 +528,31 @@ def mapPaths(paths, dir): n = SCons.Node.FS.default_fs.File('foo') mapPaths([ n, 'foo', '/bar' ], - SCons.Node.FS.default_fs.Dir('baz')) + SCons.Node.FS.default_fs.Dir('baz'), env) ...would return: [ n, 'baz/foo', '/bar' ] + + The env argument, if given, is used to perform variable + substitution on the source string(s). """ - def mapPathFunc(path, dir=dir): - if dir and is_String(path): - if not path: - return str(dir) - if os.path.isabs(path) or path[0] == '#': - return path - return dir.path_ + path + def mapPathFunc(path, dir=dir, env=env): + if is_String(path): + if env: + path = env.subst(path) + if dir: + if not path: + return str(dir) + if os.path.isabs(path) or path[0] == '#': + return path + return dir.path_ + path return path if not is_List(paths): paths = [ paths ] ret = map(mapPathFunc, paths) - if len(ret) == 1: - ret = ret[0] return ret diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index e9662537..4b93d0f1 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -477,6 +477,27 @@ class UtilTestCase(unittest.TestCase): assert cmd_list[0] == 'BAZ', cmd_list[0] assert cmd_list[1] == '**$BAR**', cmd_list[1] + def test_mapPaths(self): + """Test the mapPaths function""" + fs = SCons.Node.FS.FS() + dir=fs.Dir('foo') + file=fs.File('bar/file') + + class DummyEnv: + def subst(self, arg): + return 'bar' + + res = mapPaths([ file, 'baz', 'blat/boo', '#test' ], dir) + assert res[0] == file, res[0] + assert res[1] == os.path.normpath('foo/baz'), res[1] + assert res[2] == os.path.normpath('foo/blat/boo'), res[2] + assert res[3] == '#test', res[3] + + env=DummyEnv() + res=mapPaths('bleh', dir, env) + assert res[0] == os.path.normpath('foo/bar'), res[1] + + if __name__ == "__main__": suite = unittest.makeSuite(UtilTestCase, 'test_') if not unittest.TextTestRunner().run(suite).wasSuccessful(): diff --git a/test/CPPPATH.py b/test/CPPPATH.py index a2cae10b..4a50c67f 100644 --- a/test/CPPPATH.py +++ b/test/CPPPATH.py @@ -44,7 +44,8 @@ test = TestSCons.TestSCons() test.subdir('include', 'subdir', ['subdir', 'include'], 'inc2') test.write('SConstruct', """ -env = Environment(CPPPATH = ['include']) +env = Environment(CPPPATH = ['$FOO'], + FOO='include') obj = env.Object(target='foobar/prog', source='subdir/prog.c') env.Program(target='prog', source=obj) SConscript('subdir/SConscript', "env") diff --git a/test/F77PATH.py b/test/F77PATH.py index 3dcc2804..49aeb9a0 100644 --- a/test/F77PATH.py +++ b/test/F77PATH.py @@ -47,7 +47,7 @@ if not test.where_is('g77'): test.subdir('include', 'subdir', ['subdir', 'include'], 'inc2') test.write('SConstruct', """ -env = Environment(F77PATH = ['include'], LIBS = 'g2c') +env = Environment(F77PATH = ['$FOO'], LIBS = 'g2c', FOO='include') obj = env.Object(target='foobar/prog', source='subdir/prog.f') env.Program(target='prog', source=obj) SConscript('subdir/SConscript', "env") diff --git a/test/LIBPATH.py b/test/LIBPATH.py index 51b29989..f122519b 100644 --- a/test/LIBPATH.py +++ b/test/LIBPATH.py @@ -47,7 +47,8 @@ prog2 = test.workpath(lib_ + 'shlib') + _dll test.write('SConstruct', """ env1 = Environment(LIBS = [ 'foo1' ], - LIBPATH = [ './lib1' ]) + LIBPATH = [ '$FOO' ], + FOO='./lib1') f1 = env1.Object('f1', 'f1.c') -- 2.26.2