- 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.
# 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):
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):
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:])
def chdir(self, dir):
"""Change the current working directory for lookups.
"""
+ self.__setTopLevelDir()
if not dir is None:
self.cwd = dir
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):
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')
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
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
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")
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.
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.
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)
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]
__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()
+
+
+
+
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()