Bug fixes from Charles Crain.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 19 Dec 2001 00:22:35 +0000 (00:22 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 19 Dec 2001 00:22:35 +0000 (00:22 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@163 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/BuilderTests.py
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/FSTests.py
src/engine/SCons/Script.py
src/engine/SCons/Util.py
src/engine/SCons/UtilTests.py
test/LIBS.py
test/option--C.py

index 41a5ba7d45712efba735a03a1208a0ab93b03703..9a112df8cf097948ab21a3d64d6a91683dada2bb 100644 (file)
@@ -13,19 +13,31 @@ RELEASE 0.02 -
   - Fixed the version comment in the scons.bat (the UNIX geek used
     # instead of @rem).
 
-  - Added support for the Install method (courtesy Charles Crain).
+  - Fix to setup.py so it doesn't require a sys.argv[1] argument.
 
-  - Added support for the BuildDir method (courtesy Charles Crain).
+  From Charles Crain:
 
-  - Added the Export method (courtesy Charles Crain).
+  - Added support for the Install method.
 
-  - Documented CXXFLAGS, CXXCOM, and CPPPATH (courtesy Anthony Roach).
+  - Added support for the BuildDir method.
 
-  - Fixed SCONS_LIB_DIR to work as documented (courtesy Anthony Roach).
+  - Added the Export method.
 
-  - Made Default() accept Nodes as arguments (courtesy Anthony Roach).
+  - Fix the -C option by delaying setting the top of the FS tree.
 
-  - Fix to setup.py so it doesn't require a sys.argv[1] argument.
+  - Avoid putting the directory path on the libraries in the LIBS
+    construction variable.
+
+  - Added a GetBuildPath() method to return the full path to the
+    Node for a specified string.
+
+  From Anthony Roach:
+
+  - Documented CXXFLAGS, CXXCOM, and CPPPATH.
+
+  - Fixed SCONS_LIB_DIR to work as documented.
+
+  - Made Default() accept Nodes as arguments.
 
 
 
index 6590daf2127ab49b43af4598b15563e6fcda80ef..5beee1a9612c49fff3e9e2a667623bd120985db9 100644 (file)
@@ -297,7 +297,7 @@ class BuilderTestCase(unittest.TestCase):
         # to the other module via a direct import.
         kw['dir'] = SCons.Node.FS.default_fs.Dir('d')
         contents = apply(b4.get_contents, (), kw)
-        expect = os.path.normpath("-ld/l1 -ld/l2 -Ld/libX -Id/c -Id/p")
+        expect = os.path.normpath("-ll1 -ll2 -Ld/libX -Id/c -Id/p")
         assert contents == expect, contents + " != " + expect
 
     def test_name(self):
index 303db61d51f7b1aef3247a0a7eb5a8f83d5a5f05..6a7fcc895ff49c280ff91c10e10dfe89a3e18875 100644 (file)
@@ -127,15 +127,32 @@ class FS:
         The path argument must be a valid absolute path.
         """
         if path == None:
-            path = os.getcwd()
+            self.pathTop = os.getcwd()
+        else:
+            self.pathTop = path
         self.Root = PathDict()
-        self.Top = self.__doLookup(Dir, path)
-        self.Top.path = '.'
-        self.Top.srcpath = '.'
-        self.Top.path_ = os.path.join('.', '')
-        self.cwd = self.Top
+        self.Top = None
+
+    def set_toplevel_dir(self, path):
+        assert not self.Top, "You can only set the top-level path on an FS object that has not had its File, Dir, or Entry methods called yet."
+        self.pathTop = path
+        
+    def __setTopLevelDir(self):
+        if not self.Top:
+            self.Top = self.__doLookup(Dir, self.pathTop)
+            self.Top.path = '.'
+            self.Top.srcpath = '.'
+            self.Top.path_ = os.path.join('.', '')
+            self.cwd = self.Top
+        
+    def __hash__(self):
+        self.__setTopLevelDir()
+        return hash(self.Top)
 
     def __cmp__(self, other):
+        self.__setTopLevelDir()
+        if isinstance(other, FS):
+            other.__setTopLevelDir()
        return cmp(self.__dict__, other.__dict__)
 
     def __doLookup(self, fsclass, name, directory=None):
@@ -206,6 +223,7 @@ class FS:
         If directory is None, and name is a relative path,
         then the same applies.
         """
+        self.__setTopLevelDir()
         if name[0] == '#':
             directory = self.Top
             name = os.path.join(os.path.normpath('./'), name[1:])
@@ -216,6 +234,7 @@ class FS:
     def chdir(self, dir):
         """Change the current working directory for lookups.
         """
+        self.__setTopLevelDir()
         if not dir is None:
             self.cwd = dir
 
@@ -258,6 +277,7 @@ class FS:
     def BuildDir(self, build_dir, src_dir):
         """Link the supplied build directory to the source directory
         for purposes of building files."""
+        self.__setTopLevelDir()
         dirSrc = self.Dir(src_dir)
         dirBuild = self.Dir(build_dir)
         if not dirSrc.is_under(self.Top) or not dirBuild.is_under(self.Top):
index 0f6b8b72e4c68c37a0712d41ee59f1ddbc2fa854..6851e5ec91521bc64371b812392361e81e1c34db 100644 (file)
@@ -372,7 +372,7 @@ class FSTestCase(unittest.TestCase):
         os.chdir('..')
         fs3 = SCons.Node.FS.FS()
         assert fs1 == fs2
-        assert fs1 == fs3
+        assert fs1 != fs3
 
         # Test comparison of Entry objects
         e1 = fs3.Entry('cmp/entry')
index 15abb48e872fbe56e46b2f31b4489922358a3fff..1298a9e4c1f271455344c422cf07c18fbae6b201 100644 (file)
@@ -58,6 +58,7 @@ from SCons.Errors import *
 import SCons.Sig
 import SCons.Sig.MD5
 from SCons.Taskmaster import Taskmaster
+import SCons.Util
 
 #
 # Modules and classes that we don't use directly in this script, but
@@ -182,6 +183,14 @@ def Help(text):
 def BuildDir(build_dir, src_dir):
     SCons.Node.FS.default_fs.BuildDir(build_dir, src_dir)
 
+def GetBuildPath(files):
+    nodes = SCons.Util.scons_str2nodes(files,
+                                       SCons.Node.FS.default_fs.Entry)
+    ret = map(str, nodes)
+    if len(ret) == 1:
+        return ret[0]
+    return ret
+
 def Export(**kw):
     # A convenient shorthand to pass exports to the SConscript function.
     return kw
@@ -361,6 +370,7 @@ def options_init():
     def opt_C(opt, arg):
        try:
            os.chdir(arg)
+            SCons.Node.FS.default_fs.set_toplevel_dir(os.getcwd())
        except:
            sys.stderr.write("Could not change directory to 'arg'\n")
 
index b2850c09ab34157d08f3c7539dddee636278d4bd..1cd51d71b40a0d3b7709cd4968d24e5707a31084 100644 (file)
@@ -36,7 +36,7 @@ import string
 import re
 from UserList import UserList
 import SCons.Node.FS
-import cStringIO
+import copy
 
 def scons_str2nodes(arg, node_factory=SCons.Node.FS.default_fs.File):
     """This function converts a string or list into a list of Node instances.
@@ -255,20 +255,77 @@ def find_files(filenames, paths,
 
     return nodes
 
+class VarInterpolator:
+    def __init__(self, dest, src, prefix, suffix):
+        self.dest = dest
+        self.src = src
+        self.prefix = prefix
+        self.suffix = suffix
 
+    def prepareSrc(self, dict):
+        src = dict[self.src]
+        if not type(src) is types.ListType and not isinstance(src, UserList):
+            src = [ src ]
+        return src
+
+    def generate(self, dict):
+        if not dict.has_key(self.src):
+            dict[self.dest] = ''
+            return
+        src = self.prepareSrc(dict)
+
+        try:
+            prefix = str(dict[self.prefix])
+        except KeyError:
+            prefix=''
 
-AUTO_GEN_VARS = ( ( '_LIBFLAGS',
-                    'LIBS',
-                    'LIBLINKPREFIX',
-                    'LIBLINKSUFFIX' ),
-                  ( '_LIBDIRFLAGS',
-                    'LIBPATH',
-                    'LIBDIRPREFIX',
-                    'LIBDIRSUFFIX' ),
-                  ( '_INCFLAGS',
-                    'CPPPATH',
-                    'INCPREFIX',
-                    'INCSUFFIX' ) )
+        try:
+            suffix = str(dict[self.suffix])
+        except KeyError:
+            suffix =''
+
+        dict[self.dest] = map(lambda x, suff=suffix, pref=prefix: \
+                              pref + os.path.normpath(str(x)) + suff,
+                              src)
+
+    def instance(self, dir, fs):
+        return self
+
+class DirVarInterp(VarInterpolator):
+    def __init__(self, dest, src, prefix, suffix):
+        VarInterpolator.__init__(self, dest, src, prefix, suffix)
+        self.fs = None
+        self.Dir = None
+        self.dictInstCache = {}
+        
+    def prepareSrc(self, dict):
+        src = VarInterpolator.prepareSrc(self, dict)
+        return map(lambda x, fs=self.fs, d=self.dir: \
+                   fs.Dir(str(x), directory = d).path,
+                   src)
+
+    def instance(self, dir, fs):
+        try:
+            ret = self.dictInstCache[(dir, fs)]
+        except KeyError:
+            ret = copy.copy(self)
+            ret.fs = fs
+            ret.dir = dir
+            self.dictInstCache[(dir, fs)] = ret
+        return ret
+
+AUTO_GEN_VARS = ( VarInterpolator('_LIBFLAGS',
+                                  'LIBS',
+                                  'LIBLINKPREFIX',
+                                  'LIBLINKSUFFIX'),
+                  DirVarInterp('_LIBDIRFLAGS',
+                               'LIBPATH',
+                               'LIBDIRPREFIX',
+                               'LIBDIRSUFFIX' ),
+                  DirVarInterp('_INCFLAGS',
+                               'CPPPATH',
+                               'INCPREFIX',
+                               'INCSUFFIX') )
 
 def autogenerate(dict, fs = SCons.Node.FS.default_fs, dir = None):
     """Autogenerate the "interpolated" environment variables.
@@ -287,28 +344,6 @@ def autogenerate(dict, fs = SCons.Node.FS.default_fs, dir = None):
     is a string, with the prefix and suffix
     concatenated."""
 
-    for strVarAuto, strSrc, strPref, strSuff, in AUTO_GEN_VARS:
-        if not dict.has_key(strSrc):
-            dict[strVarAuto] = ''
-            continue
-                
-        src = dict[strSrc]
-        if not type(src) is types.ListType and not isinstance(src, UserList):
-            src = [ src ]
-        src = map(lambda x, fs=fs, d=dir: \
-                  fs.Dir(str(x), directory = d).path,
-                  src)
-
-        try:
-            prefix = str(dict[strPref])
-        except KeyError:
-            prefix=''
-
-        try:
-            suffix = str(dict[strSuff])
-        except KeyError:
-            suffix =''
+    for interp in AUTO_GEN_VARS:
+        interp.instance(dir, fs).generate(dict)
 
-        dict[strVarAuto] = map(lambda x, suff=suffix, pref=prefix: \
-                               pref + os.path.normpath(str(x)) + suff,
-                               src)
index 2952fc43ddf5b29290f4303d45c3dc35bf769c52..615e29f81f4b062ef191ac330c65f0f222a6de44 100644 (file)
@@ -179,7 +179,7 @@ class UtilTestCase(unittest.TestCase):
         dict = {'LIBS'          : [ 'foo', 'bar', 'baz' ],
                 'LIBLINKPREFIX' : 'foo',
                 'LIBLINKSUFFIX' : 'bar'}
-        autogenerate(dict)
+        autogenerate(dict, dir = SCons.Node.FS.default_fs.Dir('/xx'))
         assert len(dict['_LIBFLAGS']) == 3, dict('_LIBFLAGS')
         assert dict['_LIBFLAGS'][0] == 'foofoobar', \
                dict['_LIBFLAGS'][0]
index dec523df6b4829bb6e563326332c07bf8b12f830..8dac7be00fe51eda311761731122f6426819eaf3 100644 (file)
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import TestSCons
+import sys
+
+if sys.platform == 'win32':
+    _exe = '.exe'
+else:
+    _exe = ''
 
 test = TestSCons.TestSCons()
 
-test.pass_test()       #XXX Short-circuit until this is implemented.
+foo_exe = test.workpath('subdir/foo' + _exe)
 
 test.write('SConstruct', """
+SConscript('subdir/SConscript')
+""")
+
+test.subdir('subdir')
+
+test.write('subdir/foo.c', r"""
+void do_it();
+
+int main(void)
+{
+   do_it();
+   return 0;
+}
+""")
+
+test.write('subdir/bar.c', r"""
+#include <stdio.h>
+
+void do_it()
+{
+   printf("bar.c\n");
+}
+""")
+
+test.write('subdir/SConscript', r"""
+env = Environment(LIBS=['bar'], LIBPATH = [ '#subdir' ])
+env.Library(target='bar', source='bar.c')
+env.Program(target='foo', source='foo.c')
 """)
 
 test.run(arguments = '.')
 
+test.run(program=foo_exe, stdout='bar.c\n')
+
 test.pass_test()
+
+
+
+
index ffff484f42c9e3f87bba3dfd9e9600c5ebe4efc7..cb8c01ca95053326a497264c24743ba60e4e39ca 100644 (file)
@@ -43,27 +43,27 @@ print "SConstruct", os.getcwd()
 
 test.write(['sub', 'SConstruct'], """
 import os
-print "sub/SConstruct", os.getcwd()
+print GetBuildPath('..')
 """)
 
 test.write(['sub', 'dir', 'SConstruct'], """
 import os
-print "sub/dir/SConstruct", os.getcwd()
+print GetBuildPath('..')
 """)
 
 test.run(arguments = '-C sub',
-        stdout = "sub/SConstruct %s\n" % wpath_sub)
+        stdout = "%s\n" % wpath)
 
 test.run(arguments = '-C sub -C dir',
-        stdout = "sub/dir/SConstruct %s\n" % wpath_sub_dir)
+        stdout = "%s\n" % wpath_sub)
 
 test.run(stdout = "SConstruct %s\n" % wpath)
 
 test.run(arguments = '--directory=sub/dir',
-        stdout = "sub/dir/SConstruct %s\n" % wpath_sub_dir)
+        stdout = "%s\n" % wpath_sub)
 
 test.run(arguments = '-C %s -C %s' % (wpath_sub_dir, wpath_sub),
-        stdout = "sub/SConstruct %s\n" % wpath_sub)
+        stdout = "%s\n" % wpath)
 
 test.pass_test()