after: /biz:/foo/bar:/foo
.EE
+'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.TP
+.RI env.AppendUnique( key = val ", [...])"
+Appends the specified keyword arguments
+to the end of construction variables in the environment.
+If the Environment does not have
+the specified construction variable,
+it is simply added to the environment.
+If the construction variable being appended to is a list,
+then any value(s) that already exist in the
+construction variable will
+.I not
+be added again to the list.
+
+.ES
+env.AppendUnique(CCFLAGS = '-g', FOO = ['foo.yyy'])
+.EE
+
'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.TP
env.BitKeeper()
after: /foo/bar:/foo:/biz
.EE
+'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.TP
+.RI env.AppendUnique( key = val ", [...])"
+Appends the specified keyword arguments
+to the beginning of construction variables in the environment.
+If the Environment does not have
+the specified construction variable,
+it is simply added to the environment.
+If the construction variable being appended to is a list,
+then any value(s) that already exist in the
+construction variable will
+.I not
+be added again to the list.
+
+.ES
+env.PrependUnique(CCFLAGS = '-g', FOO = ['foo.yyy'])
+.EE
+
'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.TP
env.RCS()
- Save memory at build time by allowing Nodes to delete their build
environments after they've been built.
+ - Add AppendUnique() and PrependUnique() Environment methods, which
+ add values to construction variables like Append() and Prepend()
+ do, but suppress any duplicate elements in the list.
+
+ - Allow the 'qt' tool to still be used successfully from a copied
+ Environment. The include and library directories previously ended up
+ having the same string re-appended to the end, yielding an incorrect
+ path name.
+
From Vincent Risi:
- Add support for the bcc32, ilink32 and tlib Borland tools.
self._dict[envname][name] = nv
+ def AppendUnique(self, **kw):
+ """Append values to existing construction variables
+ in an Environment, if they're not already there.
+ """
+ kw = our_deepcopy(kw)
+ for key, val in kw.items():
+ if not self._dict.has_key(key):
+ self._dict[key] = val
+ elif SCons.Util.is_Dict(self._dict[key]) and \
+ SCons.Util.is_Dict(val):
+ self._dict[key].update(val)
+ elif SCons.Util.is_List(val):
+ dk = self._dict[key]
+ if not SCons.Util.is_List(dk):
+ dk = [dk]
+ val = filter(lambda x, dk=dk: x not in dk, val)
+ self._dict[key] = dk + val
+ else:
+ dk = self._dict[key]
+ if SCons.Util.is_List(dk):
+ if not val in dk:
+ self._dict[key] = dk + val
+ else:
+ self._dict[key] = self._dict[key] + val
+
def Copy(self, tools=None, toolpath=[], **kw):
"""Return a copy of a construction Environment. The
copy is like a Python "deep copy"--that is, independent
self._dict[envname][name] = nv
+ def PrependUnique(self, **kw):
+ """Append values to existing construction variables
+ in an Environment, if they're not already there.
+ """
+ kw = our_deepcopy(kw)
+ for key, val in kw.items():
+ if not self._dict.has_key(key):
+ self._dict[key] = val
+ elif SCons.Util.is_Dict(self._dict[key]) and \
+ SCons.Util.is_Dict(val):
+ self._dict[key].update(val)
+ elif SCons.Util.is_List(val):
+ dk = self._dict[key]
+ if not SCons.Util.is_List(dk):
+ dk = [dk]
+ val = filter(lambda x, dk=dk: x not in dk, val)
+ self._dict[key] = val + dk
+ else:
+ dk = self._dict[key]
+ if SCons.Util.is_List(dk):
+ if not val in dk:
+ self._dict[key] = val + dk
+ else:
+ self._dict[key] = val + dk
+
def Replace(self, **kw):
"""Replace existing construction variables in an Environment
with new construction variables and/or values.
RDirs=RDirs)
flags = env.subst_list('$_LIBFLAGS', 1)[0]
assert len(flags) == 3, flags
- assert flags[0] == 'foofoobar', \
+ assert flags[0] == 'foobar', \
flags[0]
- assert flags[1] == 'foobarbar', \
+ assert flags[1] == 'foobar', \
flags[1]
assert flags[2] == 'foobazbar', \
flags[2]
flags[2]
assert flags[3] == os.path.normpath('foo'), \
flags[3]
- assert flags[4] == os.path.normpath('xx/baz/barbar'), \
+ assert flags[4] == os.path.normpath('xx/baz/bar'), \
flags[4]
assert flags[5] == os.path.normpath('foo'), \
flags[5]
flags[2]
assert flags[3] == os.path.normpath('foo'), \
flags[3]
- assert flags[4] == os.path.normpath('xx/baz/barbar'), \
+ assert flags[4] == os.path.normpath('xx/baz/bar'), \
flags[4]
assert flags[5] == os.path.normpath('foo'), \
flags[5]
assert(env1['ENV']['PATH'] == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three')
assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\two;C:\mydir\num\three;C:\mydir\num\one')
+ def test_AppendUnique(self):
+ """Test appending to unique values to construction variables
+
+ This strips values that are already present when lists are
+ involved."""
+ env = Environment(AAA1 = 'a1',
+ AAA2 = 'a2',
+ AAA3 = 'a3',
+ BBB1 = ['b1'],
+ BBB2 = ['b2'],
+ BBB3 = ['b3'])
+ env.AppendUnique(AAA1 = 'a1',
+ AAA2 = ['a2'],
+ AAA3 = ['a3', 'b', 'c', 'a3'],
+ BBB1 = 'b1',
+ BBB2 = ['b2'],
+ BBB3 = ['b3', 'c', 'd', 'b3'])
+ assert env['AAA1'] == 'a1a1', env['AAA1']
+ assert env['AAA2'] == ['a2'], env['AAA2']
+ assert env['AAA3'] == ['a3', 'b', 'c'], env['AAA3']
+ assert env['BBB1'] == ['b1'], env['BBB1']
+ assert env['BBB2'] == ['b2'], env['BBB2']
+ assert env['BBB3'] == ['b3', 'c', 'd'], env['BBB3']
+
def test_Copy(self):
"""Test construction Environment copying
assert(env1['ENV']['PATH'] == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
+ def test_PrependUnique(self):
+ """Test prepending unique values to construction variables
+
+ This strips values that are already present when lists are
+ involved."""
+ env = Environment(AAA1 = 'a1',
+ AAA2 = 'a2',
+ AAA3 = 'a3',
+ BBB1 = ['b1'],
+ BBB2 = ['b2'],
+ BBB3 = ['b3'])
+ env.PrependUnique(AAA1 = 'a1',
+ AAA2 = ['a2'],
+ AAA3 = ['a3', 'b', 'c', 'a3'],
+ BBB1 = 'b1',
+ BBB2 = ['b2'],
+ BBB3 = ['b3', 'b', 'c', 'b3'])
+ assert env['AAA1'] == 'a1a1', env['AAA1']
+ assert env['AAA2'] == ['a2'], env['AAA2']
+ assert env['AAA3'] == ['b', 'c', 'a3'], env['AAA3']
+ assert env['BBB1'] == ['b1'], env['BBB1']
+ assert env['BBB2'] == ['b2'], env['BBB2']
+ assert env['BBB3'] == ['b', 'c', 'b3'], env['BBB3']
+
def test_Replace(self):
"""Test replacing construction variables in an Environment
env['LIBEMITTER'] = _Automoc('StaticObject',
uicDeclBld,mocFromHBld,mocFromCppBld)
# Of course, we need to link against the qt libraries
- env.Append(CPPPATH=os.path.join('$QTDIR', 'include'))
- env.Append(LIBPATH=os.path.join('$QTDIR', 'lib'))
- env.Append(LIBS='$QT_LIB')
+ env.AppendUnique(CPPPATH=[os.path.join('$QTDIR', 'include')])
+ env.AppendUnique(LIBPATH=[os.path.join('$QTDIR', 'lib')])
+ env.AppendUnique(LIBS=['$QT_LIB'])
def exists(env):
return _detect(env)
QT_UIC = '%s %s' % (python, test.workpath('qt','bin','myuic.py'))
##############################################################################
-# 4 test cases with 4 different operation modes
+# Test cases with different operation modes
def createSConstruct(test,place):
test.write(place, """
SConscript( sconscript )
""" % (QT, QT_LIB, QT_MOC, QT_UIC))
-test.subdir( 'work1', 'work2', 'work3', 'work4', 'work5' )
+test.subdir( 'work1', 'work2', 'work3', 'work4', 'work5', 'work6' )
##############################################################################
# 1. create a moc file from a header file.
print test.stdout()
test.fail_test()
+##############################################################################
+# 5. Test creation from a copied environment.
+
+createSConstruct(test, ['work5', 'SConstruct'])
+test.write( ['work5', 'SConscript'], """
+Import("env")
+env = env.Copy(tools=['qt'])
+env.Program('main', 'main.cpp', CXXFLAGS=['-g'])
+""")
-# look if qt is installed, and try out all builders
+test.write(['work5', 'main.cpp'], r"""
+#include "foo5.h"
+int main() { foo5(); return 0; }
+""")
+
+test.write(['qt', 'include', 'foo5.h'], """\
+#include <stdio.h>
+void
+foo5(void)
+{
+ printf("qt/include/foo5.h\\n");
+}
+""")
+
+test.run(chdir='work5')
+
+main_exe = 'main' + _exe
+test.run(program = test.workpath('work5', main_exe),
+ stdout = 'qt/include/foo5.h\n')
+
+##############################################################################
+# 6. look if qt is installed, and try out all builders
if os.environ.get('QTDIR', None):
QTDIR=os.environ['QTDIR']
- test.write( ['work5', 'SConstruct'],"""
+ test.write( ['work6', 'SConstruct'],"""
import os
dummy_env = Environment()
ENV = dummy_env['ENV']
'main.cpp'])
""")
- test.write( ['work5', 'mocFromCpp.h'],"""
+ test.write( ['work6', 'mocFromCpp.h'],"""
void mocFromCpp();
""")
- test.write( ['work5', 'mocFromCpp.cpp'],"""
+ test.write( ['work6', 'mocFromCpp.cpp'],"""
#include <qobject.h>
#include "mocFromCpp.h"
class MyClass1 : public QObject {
#include "moc_mocFromCpp.cpp"
""")
- test.write( ['work5', 'mocFromH.h'],"""
+ test.write( ['work6', 'mocFromH.h'],"""
#include <qobject.h>
class MyClass2 : public QObject {
Q_OBJECT;
void mocFromH();
""")
- test.write( ['work5', 'mocFromH.cpp'],"""
+ test.write( ['work6', 'mocFromH.cpp'],"""
#include "mocFromH.h"
MyClass2::MyClass2() : QObject() {}
}
""")
- test.write( ['work5', 'anUiFile.ui'],"""
+ test.write( ['work6', 'anUiFile.ui'],"""
<!DOCTYPE UI><UI>
<class>MyWidget</class>
<widget>
</UI>
""")
- test.write( ['work5', 'main.cpp'], """
+ test.write( ['work6', 'main.cpp'], """
#include "mocFromCpp.h"
#include "mocFromH.h"
#include "anUiFile.h"
}
""")
- test.run(chdir='work5', arguments="test_realqt" + _exe)
+ test.run(chdir='work6', arguments="test_realqt" + _exe)
QTDIR=os.environ['QTDIR']
del os.environ['QTDIR']
- test.run(chdir='work5', arguments="-c test_realqt" + _exe)
- test.run(chdir='work5', arguments="PATH=%s/bin test_realqt%s"%(QTDIR,_exe))
+ test.run(chdir='work6', arguments="-c test_realqt" + _exe)
+ test.run(chdir='work6', arguments="PATH=%s/bin test_realqt%s"%(QTDIR,_exe))
else:
print "Could not find QT, skipping test(s)."