summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/man/scons.142
-rw-r--r--src/CHANGES.txt11
-rw-r--r--src/engine/SCons/Environment.py6
-rw-r--r--src/engine/SCons/EnvironmentTests.py10
-rw-r--r--src/engine/SCons/Tool/qt.py126
-rw-r--r--test/QTFLAGS.py80
6 files changed, 186 insertions, 89 deletions
diff --git a/doc/man/scons.1 b/doc/man/scons.1
index 6b94453..931a46f 100644
--- a/doc/man/scons.1
+++ b/doc/man/scons.1
@@ -3589,6 +3589,19 @@ SConsignFile("/home/me/SCons/signatures")
'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.TP
+.RI env.SetDefault(key = val ", [...])"
+Sets construction variables to default values specified with the keyword
+arguments if (and only if) the variables are not already set.
+The following statements are equivalent:
+
+.ES
+env.SetDefault(FOO = 'foo')
+
+if not env.has_key('FOO'): env['FOO'] = 'foo'
+.EE
+
+'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.TP
.RI SetOption( name ", " value )
.TP
.RI env.SetOption( name ", " value )
@@ -5624,14 +5637,16 @@ with python's os.path.join() method,
but are listed here with the '/' separator
for easier reading.)
In addition, the construction environment
-variables CPPPATH, LIBPATH, LIBS, PROGEMITTER, SHLIBEMITTER and LIBEMITTER
+variables CPPPATH, LIBPATH and LIBS may be modified
+and the variables
+PROGEMITTER, SHLIBEMITTER and LIBEMITTER
are modified. Because the build-performance is affected when using this tool,
you have to explicitly specify it at Environment creation:
.ES
Environment(tools=['default','qt'])
.EE
-
+.IP
The qt tool supports the following operations:
.B Automatic moc file generation from header files.
@@ -5665,14 +5680,31 @@ you may need to specify duplicate=1 in calls to BuildDir. See also the correspon
Turn off scanning for mocable files. Use the Moc Builder to explicitely
specify files to run moc on.
+.IP QT_BINPATH
+The path where the qt binaries are installed.
+The default value is '$QTDIR/bin'.
+
+.IP QT_CPPPATH
+The path where the qt header files are installed.
+The default value is '$QTDIR/include'.
+Note: If you set this variable to None, the tool won't change the CPPPATH
+construction variable.
+
.IP QT_DEBUG
Prints lots of debugging information while scanning for moc files.
+.IP QT_LIBPATH
+The path where the qt libraries are installed.
+The default value is '$QTDIR/lib'.
+Note: If you set this variable to None, the tool won't change the LIBPATH
+construction variable.
+
.IP QT_LIB
-Default value is 'qt'. You may want to set this to 'qt-mt'.
+Default value is 'qt'. You may want to set this to 'qt-mt'. Note: If you set
+this variable to None, the tool won't change the LIBS variable.
.IP QT_MOC
-Default value is '$QTDIR/bin/moc'.
+Default value is '$QT_BINPATH/moc'.
.IP QT_MOCCXXPREFIX
Default value is ''. Prefix for moc output files, when source is a cxx file.
@@ -5703,7 +5735,7 @@ Default value is '$CXXFILESUFFIX'. Suffix for moc output files, when source is
a header.
.IP QT_UIC
-Default value is '$QTDIR/bin/uic'.
+Default value is '$QT_BINPATH/uic'.
.IP QT_UICDECLCOM
Command to generate header files from .ui files.
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index f1d8530..617b38f 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -25,6 +25,17 @@ RELEASE 0.97 - XXX
- Fix the Builder name returned from ListBuilders and other instances
of subclasses of the BuilderBase class.
+ From Christoph Wiedemann:
+
+ - Add an Environment.SetDefault() method that only sets values if
+ they aren't already set.
+
+ - Have the qt.py Tool not override variables already set by the user.
+
+ - Add separate $QT_BINPATH, $QT_CPPPATH and $QT_LIBPATH variables
+ so these can be set individually, instead of being hard-wired
+ relative to $QTDIR.
+
RELEASE 0.96.1 - XXX
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py
index 03f2e38..aeae272 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -919,6 +919,12 @@ class Base:
name = name[:-len(old_suffix)]
return os.path.join(dir, new_prefix+name+new_suffix)
+ def SetDefault(self, **kw):
+ for k in kw.keys():
+ if self._dict.has_key(k):
+ del kw[k]
+ apply(self.Replace, (), kw)
+
def Tool(self, tool, toolpath=[]):
tool = self.subst(tool)
return SCons.Tool.Tool(tool, map(self.subst, toolpath))(self)
diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py
index a6b8645..de09fd7 100644
--- a/src/engine/SCons/EnvironmentTests.py
+++ b/src/engine/SCons/EnvironmentTests.py
@@ -1580,6 +1580,16 @@ class EnvironmentTestCase(unittest.TestCase):
'PREFIX', 'SUFFIX',
'LIBPREFIX', 'LIBSUFFIX')
+ def test_SetDefault(self):
+ """Test the SetDefault method"""
+ env = Environment(tools = [])
+ env.SetDefault(V1 = 1)
+ env.SetDefault(V1 = 2)
+ assert env['V1'] == 1
+ env['V2'] = 2
+ env.SetDefault(V2 = 1)
+ assert env['V2'] == 2
+
def test_Tool(self):
"""Test the Tool() method"""
env = Environment(LINK='link', NONE='no-such-tool')
diff --git a/src/engine/SCons/Tool/qt.py b/src/engine/SCons/Tool/qt.py
index ee55051..c6237d3 100644
--- a/src/engine/SCons/Tool/qt.py
+++ b/src/engine/SCons/Tool/qt.py
@@ -201,6 +201,22 @@ def _detect(env):
"Could not detect qt, using empty QTDIR")
return QTDIR
+def uicEmitter(target, source, env):
+ adjustixes = SCons.Util.adjustixes
+ bs = SCons.Util.splitext(str(source[0].name))[0]
+ bs = os.path.join(str(target[0].get_dir()),bs)
+ # first target (header) is automatically added by builder
+ if len(target) < 2:
+ # second target is implementation
+ target.append(adjustixes(bs,
+ env.subst('$QT_UICIMPLPREFIX'),
+ env.subst('$QT_UICIMPLSUFFIX')))
+ if len(target) < 3:
+ # third target is moc file
+ target.append(adjustixes(bs,
+ env.subst('$QT_MOCHPREFIX'),
+ env.subst('$QT_MOCHSUFFIX')))
+ return target, source
def generate(env):
"""Add Builders and construction variables for qt to an Environment."""
@@ -209,66 +225,52 @@ def generate(env):
Builder = SCons.Builder.Builder
splitext = SCons.Util.splitext
- # the basics
- env['QTDIR'] = _detect(env)
- env['QT_MOC'] = os.path.join('$QTDIR','bin','moc')
- env['QT_UIC'] = os.path.join('$QTDIR','bin','uic')
- env['QT_LIB'] = 'qt' # may be set to qt-mt
-
- # Should the qt tool try to figure out, which sources are to be moc'ed ?
- env['QT_AUTOSCAN'] = 1
-
- # Some QT specific flags. I don't expect someone wants to
- # manipulate those ...
- env['QT_UICIMPLFLAGS'] = CLVar('')
- env['QT_UICDECLFLAGS'] = CLVar('')
- env['QT_MOCFROMHFLAGS'] = CLVar('')
- env['QT_MOCFROMCXXFLAGS'] = CLVar('-i')
-
- # suffixes/prefixes for the headers / sources to generate
- env['QT_UICDECLPREFIX'] = ''
- env['QT_UICDECLSUFFIX'] = '.h'
- env['QT_UICIMPLPREFIX'] = 'uic_'
- env['QT_UICIMPLSUFFIX'] = '$CXXFILESUFFIX'
- env['QT_MOCHPREFIX'] = 'moc_'
- env['QT_MOCHSUFFIX'] = '$CXXFILESUFFIX'
- env['QT_MOCCXXPREFIX'] = ''
- env['QT_MOCCXXSUFFIX'] = '.moc'
- env['QT_UISUFFIX'] = '.ui'
-
- def uicEmitter(target, source, env):
- adjustixes = SCons.Util.adjustixes
- bs = SCons.Util.splitext(str(source[0].name))[0]
- bs = os.path.join(str(target[0].get_dir()),bs)
- # first target (header) is automatically added by builder
- if len(target) < 2:
- # second target is implementation
- target.append(adjustixes(bs,
- env.subst('$QT_UICIMPLPREFIX'),
- env.subst('$QT_UICIMPLSUFFIX')))
- if len(target) < 3:
- # third target is moc file
- target.append(adjustixes(bs,
- env.subst('$QT_MOCHPREFIX'),
- env.subst('$QT_MOCHSUFFIX')))
- return target, source
-
- # Commands for the qt support ...
- # command to generate header, implementation and moc-file from a .ui file
- env['QT_UICCOM'] = [
- CLVar('$QT_UIC $QT_UICDECLFLAGS -o ${TARGETS[0]} $SOURCE'),
- CLVar('$QT_UIC $QT_UICIMPLFLAGS -impl ${TARGETS[0].file} '
- '-o ${TARGETS[1]} $SOURCE'),
- CLVar('$QT_MOC $QT_MOCFROMHFLAGS -o ${TARGETS[2]} ${TARGETS[0]}')]
- # command to generate meta object information for a class declarated
- # in a header
- env['QT_MOCFROMHCOM'] = (
- '$QT_MOC $QT_MOCFROMHFLAGS -o ${TARGETS[0]} $SOURCE')
- # command to generate meta object information for a class declarated
- # in a cpp file
- env['QT_MOCFROMCXXCOM'] = [
- CLVar('$QT_MOC $QT_MOCFROMCXXFLAGS -o ${TARGETS[0]} $SOURCE'),
- Action(checkMocIncluded,None)]
+ env.SetDefault(QTDIR = _detect(env),
+ QT_BINPATH = os.path.join('$QTDIR', 'bin'),
+ QT_CPPPATH = os.path.join('$QTDIR', 'include'),
+ QT_LIBPATH = os.path.join('$QTDIR', 'lib'),
+ QT_MOC = os.path.join('$QT_BINPATH','moc'),
+ QT_UIC = os.path.join('$QT_BINPATH','uic'),
+ QT_LIB = 'qt', # may be set to qt-mt
+
+ QT_AUTOSCAN = 1, # scan for moc'able sources
+
+ # Some QT specific flags. I don't expect someone wants to
+ # manipulate those ...
+ QT_UICIMPLFLAGS = CLVar(''),
+ QT_UICDECLFLAGS = CLVar(''),
+ QT_MOCFROMHFLAGS = CLVar(''),
+ QT_MOCFROMCXXFLAGS = CLVar('-i'),
+
+ # suffixes/prefixes for the headers / sources to generate
+ QT_UICDECLPREFIX = '',
+ QT_UICDECLSUFFIX = '.h',
+ QT_UICIMPLPREFIX = 'uic_',
+ QT_UICIMPLSUFFIX = '$CXXFILESUFFIX',
+ QT_MOCHPREFIX = 'moc_',
+ QT_MOCHSUFFIX = '$CXXFILESUFFIX',
+ QT_MOCCXXPREFIX = '',
+ QT_MOCCXXSUFFIX = '.moc',
+ QT_UISUFFIX = '.ui',
+
+ # Commands for the qt support ...
+ # command to generate header, implementation and moc-file
+ # from a .ui file
+ QT_UICCOM = [
+ CLVar('$QT_UIC $QT_UICDECLFLAGS -o ${TARGETS[0]} $SOURCE'),
+ CLVar('$QT_UIC $QT_UICIMPLFLAGS -impl ${TARGETS[0].file} '
+ '-o ${TARGETS[1]} $SOURCE'),
+ CLVar('$QT_MOC $QT_MOCFROMHFLAGS -o ${TARGETS[2]} ${TARGETS[0]}')],
+ # command to generate meta object information for a class
+ # declarated in a header
+ QT_MOCFROMHCOM = (
+ '$QT_MOC $QT_MOCFROMHFLAGS -o ${TARGETS[0]} $SOURCE'),
+ # command to generate meta object information for a class
+ # declarated in a cpp file
+ QT_MOCFROMCXXCOM = [
+ CLVar('$QT_MOC $QT_MOCFROMCXXFLAGS -o ${TARGETS[0]} $SOURCE'),
+ Action(checkMocIncluded,None)])
+
# ... and the corresponding builders
uicBld = Builder(action='$QT_UICCOM',
emitter=uicEmitter,
@@ -301,8 +303,8 @@ def generate(env):
SHLIBEMITTER=[AutomocShared],
LIBEMITTER =[AutomocStatic],
# Of course, we need to link against the qt libraries
- CPPPATH=[os.path.join('$QTDIR', 'include')],
- LIBPATH=[os.path.join('$QTDIR', 'lib')],
+ CPPPATH=["$QT_CPPPATH"],
+ LIBPATH=["$QT_LIBPATH"],
LIBS=['$QT_LIB'])
def exists(env):
diff --git a/test/QTFLAGS.py b/test/QTFLAGS.py
index 46c54df..a07c2c6 100644
--- a/test/QTFLAGS.py
+++ b/test/QTFLAGS.py
@@ -36,7 +36,8 @@ _exe = TestSCons._exe
test = TestSCons.TestSCons()
-test.subdir( 'qt', ['qt', 'bin'], ['qt', 'include'], ['qt', 'lib'] )
+test.subdir( 'qt', ['qt', 'bin'], ['qt', 'include'], ['qt', 'lib'],
+ 'work1', 'work2')
# create a dummy qt installation
@@ -125,8 +126,6 @@ QT_LIB = 'myqt'
QT_MOC = '%s %s' % (python, test.workpath('qt','bin','mymoc.py'))
QT_UIC = '%s %s' % (python, test.workpath('qt','bin','myuic.py'))
-# 3 test cases with 3 different operation modes
-
def createSConstruct(test,place,overrides):
test.write(place, """
env = Environment(QTDIR = r'%s',
@@ -149,7 +148,7 @@ SConscript( sconscript )
""" % (QT, QT_LIB, QT_MOC, QT_UIC, overrides))
-createSConstruct(test, ['SConstruct'],
+createSConstruct(test, ['work1', 'SConstruct'],
"""QT_UICIMPLFLAGS='-x',
QT_UICDECLFLAGS='-y',
QT_MOCFROMHFLAGS='-z',
@@ -163,7 +162,7 @@ createSConstruct(test, ['SConstruct'],
QT_MOCCXXPREFIX='moc',
QT_MOCCXXSUFFIX='.inl',
QT_UISUFFIX='.myui',""")
-test.write('SConscript',"""
+test.write(['work1', 'SConscript'],"""
Import("env")
env.Program('mytest', ['mocFromH.cpp',
'mocFromCpp.cpp',
@@ -172,34 +171,34 @@ env.Program('mytest', ['mocFromH.cpp',
'main.cpp'])
""")
-test.write('mocFromH.hpp', """
+test.write(['work1', 'mocFromH.hpp'], """
#include "my_qobject.h"
void mocFromH() Q_OBJECT
""")
-test.write('mocFromH.cpp', """
+test.write(['work1', 'mocFromH.cpp'], """
#include "mocFromH.hpp"
""")
-test.write('mocFromCpp.cpp', """
+test.write(['work1', 'mocFromCpp.cpp'], """
#include "my_qobject.h"
void mocFromCpp() Q_OBJECT
#include "mocmocFromCpp.inl"
""")
-test.write('an_ui_file.myui', """
+test.write(['work1', 'an_ui_file.myui'], """
void an_ui_file()
""")
-test.write('another_ui_file.myui', """
+test.write(['work1', 'another_ui_file.myui'], """
void another_ui_file()
""")
-test.write('another_ui_file.desc.hpp', """
+test.write(['work1', 'another_ui_file.desc.hpp'], """
/* just a dependency checker */
""")
-test.write('main.cpp', """
+test.write(['work1', 'main.cpp'], """
#include "mocFromH.hpp"
#include "uic-an_ui_file.hpp"
#include "uic-another_ui_file.hpp"
@@ -213,21 +212,21 @@ int main() {
}
""")
-test.run( arguments = "mytest" + _exe )
+test.run(chdir = 'work1', arguments = "mytest" + _exe)
-test.must_exist('mmmmocFromH.cxx',
- 'mocmocFromCpp.inl',
- 'an_ui_file.cxx',
- 'uic-an_ui_file.hpp',
- 'mmman_ui_file.cxx',
- 'another_ui_file.cxx',
- 'uic-another_ui_file.hpp',
- 'mmmanother_ui_file.cxx')
+test.must_exist(['work1', 'mmmmocFromH.cxx'],
+ ['work1', 'mocmocFromCpp.inl'],
+ ['work1', 'an_ui_file.cxx'],
+ ['work1', 'uic-an_ui_file.hpp'],
+ ['work1', 'mmman_ui_file.cxx'],
+ ['work1', 'another_ui_file.cxx'],
+ ['work1', 'uic-another_ui_file.hpp'],
+ ['work1', 'mmmanother_ui_file.cxx'])
def _flagTest(test,fileToContentsStart):
import string
for f,c in fileToContentsStart.items():
- if string.find(test.read(f), c) != 0:
+ if string.find(test.read(test.workpath('work1', f)), c) != 0:
return 1
return 0
@@ -237,4 +236,41 @@ test.fail_test(_flagTest(test, {'mmmmocFromH.cxx':'/* mymoc.py -z */',
'uic-an_ui_file.hpp':'/* myuic.py -y */',
'mmman_ui_file.cxx':'/* mymoc.py -z */'}))
+test.write(['work2', 'SConstruct'], """
+import os.path
+env1 = Environment(tools=['qt'],
+ QTDIR = r'%(QTDIR)s',
+ QT_BINPATH='$QTDIR/bin64',
+ QT_LIBPATH='$QTDIR/lib64',
+ QT_CPPPATH='$QTDIR/h64')
+
+if not env1.subst('$CPPPATH') == os.path.join(r'%(QTDIR)s', 'h64'):
+ print env1.subst('$CPPPATH')
+ Exit(1)
+if not env1.subst('$LIBPATH') == os.path.join(r'%(QTDIR)s', 'lib64'):
+ print env1.subst('$LIBPATH')
+ Exit(2)
+if not env1.subst('$QT_MOC') == os.path.join(r'%(QTDIR)s', 'bin64', 'moc'):
+ print env1.subst('$QT_MOC')
+ Exit(3)
+
+env2 = Environment(tools=['default', 'qt'],
+ QTDIR = None,
+ QT_LIB = None,
+ QT_CPPPATH = None,
+ QT_LIBPATH = None)
+
+env2.Program('main.cpp')
+""" % {'QTDIR':QT})
+
+test.write(['work2', 'main.cpp'], """
+int main() { return 0; }
+""")
+
+# Ignore stderr, because if Qt is not installed,
+# there may be a warning about an empty QTDIR on stderr.
+test.run(chdir='work2', stderr=None)
+
+test.must_exist(['work2', 'main' + _exe])
+
test.pass_test()