Repository: SCons/scons (language: python)

Issue:
Clean up Node.FS classes.
This issue was originally created at: 2001-07-18 22:00:00.
This issue was reported by: `stevenknight`.
stevenknight said at 2001-07-18 22:00:00
>Requirements sent via email.

issues@scons said at 2001-07-18 22:00:00
>Converted from SourceForge task item 34780

stevenknight said at 2006-05-20 20:47:53
>No white space in keyword.




Discussion / hints:
No failed Java tests with Mint 17 JDK 1.8 for python 2.7 and python 3.5
Does it work with your changes if the sources are class files? 
The JAR.py test has some other tests which pass class files directly to the Jar builder, also I tested that independently with one of my projects.
Here's the manpage for the Jar builder:

```
Jar() , env.Jar()
Builds a Java archive (.jar) file from the specified list of sources. Any directories in the source list will be searched for .class files). Any .java files in the source list will be compiled to .class files by calling the Java Builder.

If the $JARCHDIR value is set, the jar command will change to the specified directory using the -C option. If $JARCHDIR is not set explicitly, SCons will use the top of any subdirectory tree in which Java .class were built by the Java Builder.

If the contents any of the source files begin with the string Manifest-Version, the file is assumed to be a manifest and is passed to the jar command with the m option set.

env.Jar(target = 'foo.jar', source = 'classes')

env.Jar(target = 'bar.jar',
        source = ['bar1.java', 'bar2.java'])
```

So the jar builder should accept both directories (which should get searched for .class files), or java files which should get compiled to class files.
Regexing the Java tests with `grep -rPzo 'Jar.*.\[Jj][Aa][Vv][Aa]'` and `grep -rPzo '.\[Jj][Aa][Vv][Aa].*Jar'` only turns up one test (multi-step.py) which tests for Jar taking in .java as a source. 

Maybe a source with .java should be in the JAR.py test for completeness. Other than that, I think this fixes the JAR builder.
Added another piece to the JAR.py test to test for java source files as a source to the Jar builder. Ran the tests again with JDK 1.8, python2.7 and python3.5.

Fix patch:
diff --git a/CHANGES.txt b/CHANGES.txt
index 6052a21a3e..df06c2fd7e 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -41,6 +41,9 @@ RELEASE  VERSION/DATE TO BE FILLED IN LATER
     - Fixed Issue #4275 - when outputting compilation db and TEMPFILE was in use, the compilation db would have
       command lines using the generated tempfile for long command lines, instead of the full command line for
       the compilation step for the source/target pair.
+    - Renamed the qt tools to qt3 since the logic in that tool is only for QT version 3.  Renamed all env vars
+      which affect qt3 from QT_ to QT3_.  If you are still using SCons to build QT 3 code, you'll need to update
+      your SConscripts.  Note that using 'qt' tool has been deprecated for some time.
 
   From David H:
     - Added JAVAPROCESSORPATH construction variable which populates -processorpath.
diff --git a/RELEASE.txt b/RELEASE.txt
index 91dbb862c3..32bb945372 100644
--- a/RELEASE.txt
+++ b/RELEASE.txt
@@ -65,6 +65,11 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY
   always emitted in the order entered. Sorting is no longer required
   after Python interpreter improvements.  There might be a one-time 
   rebuild of targets that involved such sorted keys in their actions.
+- Renamed the 'qt' tools to 'qt3' since the logic in that tool is only for QT version 3.  
+  Renamed all env vars which affect qt3 from QT_ to QT3_.  If you are still using SCons
+  to build QT 3 code, you'll need to update your SConscripts.  Note that using 'qt' tool 
+  has been deprecated for some time.
+
 
 FIXES
 -----
diff --git a/SCons/Tool/qt.py b/SCons/Tool/qt.py
index ff995657db..607b58d838 100644
--- a/SCons/Tool/qt.py
+++ b/SCons/Tool/qt.py
@@ -21,351 +21,18 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-"""Tool-specific initialization for Qt.
-
-There normally shouldn't be any need to import this module directly.
-It will usually be imported through the generic SCons.Tool.Tool()
-selection method.
 """
-
-import os.path
-import re
-
-import SCons.Action
-import SCons.Builder
-import SCons.Defaults
-import SCons.Scanner
-import SCons.Tool
-import SCons.Util
-import SCons.Tool.cxx
-import SCons.Warnings
-cplusplus = SCons.Tool.cxx
-
-class ToolQtWarning(SCons.Warnings.SConsWarning):
-    pass
-
-class GeneratedMocFileNotIncluded(ToolQtWarning):
-    pass
-
-class QtdirNotFound(ToolQtWarning):
-    pass
-
-SCons.Warnings.enableWarningClass(ToolQtWarning)
-
-header_extensions = [".h", ".hxx", ".hpp", ".hh"]
-if SCons.Util.case_sensitive_suffixes('.h', '.H'):
-    header_extensions.append('.H')
-
-cxx_suffixes = cplusplus.CXXSuffixes
-
-
-def find_platform_specific_qt_paths():
-    """
-    find non-standard QT paths
-
-    If the platform does not put QT tools in standard search paths,
-    the path is expected to be set using QTDIR. SCons violates
-    the normal rule of not pulling from the user's environment
-    in this case.  However, some test cases try to validate what
-    happens when QTDIR is unset, so we need to try to make a guess.
-
-    :return: a guess at a path
-    """
-
-    # qt_bin_dirs = []
-    qt_bin_dir = None
-    if os.path.isfile('/etc/redhat-release'):
-        with open('/etc/redhat-release','r') as rr:
-            lines = rr.readlines()
-            distro = lines[0].split()[0]
-        if distro == 'CentOS':
-            # Centos installs QT under /usr/{lib,lib64}/qt{4,5,-3.3}/bin
-            # so we need to handle this differently
-            # qt_bin_dirs = glob.glob('/usr/lib64/qt*/bin')
-            # TODO: all current Fedoras do the same, need to look deeper here.
-            qt_bin_dir = '/usr/lib64/qt-3.3/bin'
-
-    return qt_bin_dir
-
-
-QT_BIN_DIR = find_platform_specific_qt_paths()
-
-def checkMocIncluded(target, source, env):
-    moc = target[0]
-    cpp = source[0]
-    # looks like cpp.includes is cleared before the build stage :-(
-    # not really sure about the path transformations (moc.cwd? cpp.cwd?) :-/
-    path = SCons.Defaults.CScan.path(env, moc.cwd)
-    includes = SCons.Defaults.CScan(cpp, env, path)
-    if moc not in includes:
-        SCons.Warnings.warn(
-            GeneratedMocFileNotIncluded,
-            "Generated moc file '%s' is not included by '%s'" %
-            (str(moc), str(cpp)))
-
-def find_file(filename, paths, node_factory):
-    for dir in paths:
-        node = node_factory(filename, dir)
-        if node.rexists():
-            return node
-    return None
-
-class _Automoc:
-    """
-    Callable class, which works as an emitter for Programs, SharedLibraries and
-    StaticLibraries.
-    """
-
-    def __init__(self, objBuilderName):
-        self.objBuilderName = objBuilderName
-
-    def __call__(self, target, source, env):
-        """
-        Smart autoscan function. Gets the list of objects for the Program
-        or Lib. Adds objects and builders for the special qt files.
-        """
-        try:
-            if int(env.subst('$QT_AUTOSCAN')) == 0:
-                return target, source
-        except ValueError:
-            pass
-        try:
-            debug = int(env.subst('$QT_DEBUG'))
-        except ValueError:
-            debug = 0
-
-        # some shortcuts used in the scanner
-        splitext = SCons.Util.splitext
-        objBuilder = getattr(env, self.objBuilderName)
-
-        # some regular expressions:
-        # Q_OBJECT detection
-        q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]')
-        # cxx and c comment 'eater'
-        #comment = re.compile(r'(//.*)|(/\*(([^*])|(\*[^/]))*\*/)')
-        # CW: something must be wrong with the regexp. See also bug #998222
-        #     CURRENTLY THERE IS NO TEST CASE FOR THAT
-
-        # The following is kind of hacky to get builders working properly (FIXME)
-        objBuilderEnv = objBuilder.env
-        objBuilder.env = env
-        mocBuilderEnv = env.Moc.env
-        env.Moc.env = env
-
-        # make a deep copy for the result; MocH objects will be appended
-        out_sources = source[:]
-
-        for obj in source:
-            if not obj.has_builder():
-                # binary obj file provided
-                if debug:
-                    print("scons: qt: '%s' seems to be a binary. Discarded." % str(obj))
-                continue
-            cpp = obj.sources[0]
-            if not splitext(str(cpp))[1] in cxx_suffixes:
-                if debug:
-                    print("scons: qt: '%s' is no cxx file. Discarded." % str(cpp))
-                # c or fortran source
-                continue
-            #cpp_contents = comment.sub('', cpp.get_text_contents())
-            if debug:
-                print("scons: qt: Getting contents of %s" % cpp)
-            cpp_contents = cpp.get_text_contents()
-            h=None
-            for h_ext in header_extensions:
-                # try to find the header file in the corresponding source
-                # directory
-                hname = splitext(cpp.name)[0] + h_ext
-                h = find_file(hname, (cpp.get_dir(),), env.File)
-                if h:
-                    if debug:
-                        print("scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp)))
-                    #h_contents = comment.sub('', h.get_text_contents())
-                    h_contents = h.get_text_contents()
-                    break
-            if not h and debug:
-                print("scons: qt: no header for '%s'." % (str(cpp)))
-            if h and q_object_search.search(h_contents):
-                # h file with the Q_OBJECT macro found -> add moc_cpp
-                moc_cpp = env.Moc(h)
-                moc_o = objBuilder(moc_cpp)
-                out_sources.append(moc_o)
-                #moc_cpp.target_scanner = SCons.Defaults.CScan
-                if debug:
-                    print("scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp)))
-            if cpp and q_object_search.search(cpp_contents):
-                # cpp file with Q_OBJECT macro found -> add moc
-                # (to be included in cpp)
-                moc = env.Moc(cpp)
-                env.Ignore(moc, moc)
-                if debug:
-                    print("scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc)))
-                #moc.source_scanner = SCons.Defaults.CScan
-        # restore the original env attributes (FIXME)
-        objBuilder.env = objBuilderEnv
-        env.Moc.env = mocBuilderEnv
-
-        return (target, out_sources)
-
-AutomocShared = _Automoc('SharedObject')
-AutomocStatic = _Automoc('StaticObject')
-
-def _detect(env):
-    """Not really safe, but fast method to detect the QT library"""
-
-    QTDIR = env.get('QTDIR',None)
-    if not QTDIR:
-        QTDIR = os.environ.get('QTDIR',None)
-    if not QTDIR:
-        moc = env.WhereIs('moc') or env.WhereIs('moc',QT_BIN_DIR)
-        if moc:
-            QTDIR = os.path.dirname(os.path.dirname(moc))
-            SCons.Warnings.warn(
-                QtdirNotFound,
-                "Could not detect qt, using moc executable as a hint (QTDIR=%s)" % QTDIR)
-        else:
-            QTDIR = None
-            SCons.Warnings.warn(
-                QtdirNotFound,
-                "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 uicScannerFunc(node, env, path):
-    lookout = []
-    lookout.extend(env['CPPPATH'])
-    lookout.append(str(node.rfile().dir))
-    includes = re.findall("<include.*?>(.*?)</include>", node.get_text_contents())
-    result = []
-    for incFile in includes:
-        dep = env.FindFile(incFile,lookout)
-        if dep:
-            result.append(dep)
-    return result
-
-uicScanner = SCons.Scanner.ScannerBase(uicScannerFunc,
-                                name = "UicScanner",
-                                node_class = SCons.Node.FS.File,
-                                node_factory = SCons.Node.FS.File,
-                                recursive = 0)
+This is a fake tool to instruct any builds still referencing 'qt' instead
+of the new 'qt3' or a newer QT builder how to fix their now broken build.
+"""
+import SCons.Errors
 
 def generate(env):
-    """Add Builders and construction variables for qt to an Environment."""
-    CLVar = SCons.Util.CLVar
-    Action = SCons.Action.Action
-    Builder = SCons.Builder.Builder
-
-    SCons.Warnings.warn(
-        SCons.Warnings.ToolQtDeprecatedWarning, "Tool module for Qt version 3 is deprecated"
+    raise SCons.Errors.UserError(
+        "Deprecated tool 'qt' renamed to 'qt3'. "
+        "Please update your build accordingly. "
+        "'qt3' will be removed entirely in a future release."
     )
 
-    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=SCons.Action.Action('$QT_UICCOM', '$QT_UICCOMSTR'),
-                     emitter=uicEmitter,
-                     src_suffix='$QT_UISUFFIX',
-                     suffix='$QT_UICDECLSUFFIX',
-                     prefix='$QT_UICDECLPREFIX',
-                     source_scanner=uicScanner)
-    mocBld = Builder(action={}, prefix={}, suffix={})
-    for h in header_extensions:
-        act = SCons.Action.Action('$QT_MOCFROMHCOM', '$QT_MOCFROMHCOMSTR')
-        mocBld.add_action(h, act)
-        mocBld.prefix[h] = '$QT_MOCHPREFIX'
-        mocBld.suffix[h] = '$QT_MOCHSUFFIX'
-    for cxx in cxx_suffixes:
-        act = SCons.Action.Action('$QT_MOCFROMCXXCOM', '$QT_MOCFROMCXXCOMSTR')
-        mocBld.add_action(cxx, act)
-        mocBld.prefix[cxx] = '$QT_MOCCXXPREFIX'
-        mocBld.suffix[cxx] = '$QT_MOCCXXSUFFIX'
-
-    # register the builders
-    env['BUILDERS']['Uic'] = uicBld
-    env['BUILDERS']['Moc'] = mocBld
-    static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
-    static_obj.add_src_builder('Uic')
-    shared_obj.add_src_builder('Uic')
-
-    # We use the emitters of Program / StaticLibrary / SharedLibrary
-    # to scan for moc'able files
-    # We can't refer to the builders directly, we have to fetch them
-    # as Environment attributes because that sets them up to be called
-    # correctly later by our emitter.
-    env.AppendUnique(PROGEMITTER =[AutomocStatic],
-                     SHLIBEMITTER=[AutomocShared],
-                     LDMODULEEMITTER=[AutomocShared],
-                     LIBEMITTER  =[AutomocStatic],
-                     # Of course, we need to link against the qt libraries
-                     CPPPATH=["$QT_CPPPATH"],
-                     LIBPATH=["$QT_LIBPATH"],
-                     LIBS=['$QT_LIB'])
-
 def exists(env):
-    return _detect(env)
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
+    return False
diff --git a/SCons/Tool/qt.xml b/SCons/Tool/qt.xml
index 5298a82c43..3ba71b92cd 100644
--- a/SCons/Tool/qt.xml
+++ b/SCons/Tool/qt.xml
@@ -26,422 +26,9 @@ See its __doc__ string for a discussion of the format.
 <tool name="qt">
 <summary>
 <para>
-Sets &consvars; for building Qt3 applications.
-</para>
-
-<note><para>
-This tool is only suitable for building targeted to Qt3,
-which is obsolete
-(<emphasis>the tool is deprecated since 4.3</emphasis>).
-There are contributed tools for Qt4 and Qt5, see
-<ulink url="https://github.com/SCons/scons-contrib">
-https://github.com/SCons/scons-contrib</ulink>.
-Qt4 has also passed end of life for standard support (in Dec 2015).
-</para></note>
-
-<para>
-Note paths for these &consvars; are assembled
-using the <function>os.path.join</function> method
-so they will have the appropriate separator at runtime,
-but are listed here in the various
-entries only with the <literal>'/'</literal> separator
-for simplicity.
-</para>
-
-<para>
-In addition, the &consvars;
-&cv-link-CPPPATH;,
-&cv-link-LIBPATH; and
-&cv-link-LIBS; may be modified
-and the variables
-&cv-link-PROGEMITTER;, &cv-link-SHLIBEMITTER; and &cv-link-LIBEMITTER;
-are modified. Because the build-performance is affected when using this tool,
-you have to explicitly specify it at Environment creation:
-</para>
-
-<example_commands>
-Environment(tools=['default','qt'])
-</example_commands>
-
-<para>
-The &t-qt; tool supports the following operations:
-</para>
-
-<para>
-<emphasis role="strong">Automatic moc file generation from header files.</emphasis>
-You do not have to specify moc files explicitly, the tool does it for you.
-However, there are a few preconditions to do so: Your header file must have
-the same filebase as your implementation file and must stay in the same
-directory. It must have one of the suffixes
-<filename>.h</filename>,
-<filename>.hpp</filename>,
-<filename>.H</filename>,
-<filename>.hxx</filename>,
-<filename>.hh</filename>.
-You can turn off automatic moc file generation by setting
-&cv-link-QT_AUTOSCAN; to <constant>False</constant>.
-See also the corresponding
-&b-link-Moc; Builder.
-</para>
-
-<para>
-<emphasis role="strong">Automatic moc file generation from C++ files.</emphasis>
-As described in the Qt documentation, include the moc file at the end of
-the C++ file. Note that you have to include the file, which is generated
-by the transformation
-<literal>${QT_MOCCXXPREFIX}&lt;basename&gt;${QT_MOCCXXSUFFIX}</literal>, by default
-<filename>&lt;basename&gt;.mo</filename>. A warning is generated after building the moc file if you
-do not include the correct file. If you are using &f-link-VariantDir;, you may
-need to specify <parameter>duplicate=True</parameter>.
-You can turn off automatic moc file generation by setting &cv-QT_AUTOSCAN; to
-<literal>False</literal>. See also the corresponding
-&b-link-Moc; Builder.
-</para>
-
-<para>
-<emphasis role="strong">Automatic handling of .ui files.</emphasis>
-The implementation files generated from <filename>.ui</filename>
-files are handled much the same as yacc or lex files.
-Each <command>.ui</command> file given as a source of &b-link-Program;,
-&b-link-Library; or &b-link-SharedLibrary;
-will generate three files: the declaration file, the
-implementation file and a moc file. Because there are also generated headers,
-you may need to specify <parameter>duplicate=True</parameter> in calls to
-&f-link-VariantDir;.
-See also the corresponding
-&b-link-Uic; Builder.
+Placeholder tool to alert anyone still using qt tools to switch to qt3 or newer tool.
 </para>
 </summary>
-<sets>
-<item>QTDIR</item>
-<item>QT_BINPATH</item>
-<item>QT_CPPPATH</item>
-<item>QT_LIBPATH</item>
-<item>QT_MOC</item>
-<item>QT_UIC</item>
-<item>QT_LIB</item>
-<item>QT_AUTOSCAN</item>
-<item>QT_UICIMPLFLAGS</item>
-<item>QT_UICDECLFLAGS</item>
-<item>QT_MOCFROMHFLAGS</item>
-<item>QT_MOCFROMCXXFLAGS</item>
-<item>QT_UICDECLPREFIX</item>
-<item>QT_UICDECLSUFFIX</item>
-<item>QT_UICIMPLPREFIX</item>
-<item>QT_UICIMPLSUFFIX</item>
-<item>QT_MOCHPREFIX</item>
-<item>QT_MOCHSUFFIX</item>
-<item>QT_MOCCXXPREFIX</item>
-<item>QT_MOCCXXSUFFIX</item>
-<item>QT_UISUFFIX</item>
-<item>QT_UICCOM</item>
-<item>QT_MOCFROMHCOM</item>
-<item>QT_MOCFROMCXXCOM</item>
-</sets>
-<uses>
-<item>QTDIR</item>
-</uses>
 </tool>
 
-<builder name="Moc">
-<summary>
-<para>
-Builds an output file from a <command>moc</command> input file.
-<command>moc</command> input files are either header files or C++ files.
-This builder is only available after using the
-tool &t-link-qt;. See the &cv-link-QTDIR; variable for more information.
-Example:
-</para>
-
-<example_commands>
-env.Moc('foo.h')  # generates moc_foo.cc
-env.Moc('foo.cpp')  # generates foo.moc
-</example_commands>
-</summary>
-</builder>
-
-<builder name="Uic">
-<summary>
-<para>
-Builds a header file, an implementation file and a moc file from an ui file.
-and returns the corresponding nodes in the that order.
-This builder is only available after using the tool &t-link-qt;.
-Note: you can specify <filename>.ui</filename> files directly as source
-files to the &b-link-Program;,
-&b-link-Library; and &b-link-SharedLibrary; builders
-without using this builder. Using this builder lets you override the standard
-naming conventions (be careful: prefixes are always prepended to names of
-built files; if you don't want prefixes, you may set them to ``).
-See the &cv-link-QTDIR; variable for more information.
-Example:
-</para>
-
-<example_commands>
-env.Uic('foo.ui')  # -> ['foo.h', 'uic_foo.cc', 'moc_foo.cc']
-env.Uic(
-    target=Split('include/foo.h gen/uicfoo.cc gen/mocfoo.cc'),
-    source='foo.ui'
-)  # -> ['include/foo.h', 'gen/uicfoo.cc', 'gen/mocfoo.cc']
-</example_commands>
-</summary>
-</builder>
-
-<cvar name="QTDIR">
-<summary>
-<para>
-The path to the Qt installation to build against.
-If not already set,
-&t-link-qt; tool tries to obtain this from
-<varname>os.environ</varname>;
-if not found there, it tries to make a guess.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_AUTOSCAN">
-<summary>
-<para>
-Turn off scanning for mocable files. Use the &b-link-Moc; Builder to explicitly
-specify files to run <command>moc</command> on.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_BINPATH">
-<summary>
-<para>
-The path where the Qt binaries are installed.
-The default value is '&cv-link-QTDIR;<filename>/bin</filename>'.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_CPPPATH">
-<summary>
-<para>
-The path where the Qt header files are installed.
-The default value is '&cv-link-QTDIR;/include'.
-Note: If you set this variable to <constant>None</constant>,
-the tool won't change the &cv-link-CPPPATH;
-construction variable.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_DEBUG">
-<summary>
-<para>
-Prints lots of debugging information while scanning for moc files.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_LIB">
-<summary>
-<para>
-Default value is <literal>'qt'</literal>.
-You may want to set this to <literal>'qt-mt'</literal>.
-Note: If you set this variable to <constant>None</constant>,
-the tool won't change the &cv-link-LIBS; variable.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_LIBPATH">
-<summary>
-<para>
-The path where the Qt libraries are installed.
-The default value is '&cv-link-QTDIR;<filename>/lib</filename>'.
-Note: If you set this variable to <constant>None</constant>,
-the tool won't change the &cv-link-LIBPATH;
-construction variable.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_MOC">
-<summary>
-<para>
-Default value is '&cv-link-QT_BINPATH;<filename>/moc</filename>'.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_MOCCXXPREFIX">
-<summary>
-<para>
-Default value is <literal>''</literal>.
-Prefix for <command>moc</command> output files when source is a C++ file.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_MOCCXXSUFFIX">
-<summary>
-<para>
-Default value is <literal>'.moc'</literal>.
-Suffix for <command>moc</command> output files when source is a C++ file.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_MOCFROMCXXFLAGS">
-<summary>
-<para>
-Default value is <literal>'-i'</literal>.
-These flags are passed to <command>moc</command> when moccing a C++ file.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_MOCFROMCXXCOM">
-<summary>
-<para>
-Command to generate a moc file from a C++ file.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_MOCFROMCXXCOMSTR">
-<summary>
-<para>
-The string displayed when generating a moc file from a C++ file.
-If this is not set, then &cv-link-QT_MOCFROMCXXCOM; (the command line) is displayed.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_MOCFROMHCOM">
-<summary>
-<para>
-Command to generate a moc file from a header.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_MOCFROMHCOMSTR">
-<summary>
-<para>
-The string displayed when generating a moc file from a C++ file.
-If this is not set, then &cv-link-QT_MOCFROMHCOM; (the command line) is displayed.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_MOCFROMHFLAGS">
-<summary>
-<para>
-Default value is <literal>''</literal>. These flags are passed to <command>moc</command>
-when moccing a header file.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_MOCHPREFIX">
-<summary>
-<para>
-Default value is <literal>'moc_'</literal>.
-Prefix for <command>moc</command> output files when source is a header.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_MOCHSUFFIX">
-<summary>
-<para>
-Default value is '&cv-link-CXXFILESUFFIX;'.
-Suffix for moc output files when source is a header.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_UIC">
-<summary>
-<para>
-Default value is '&cv-link-QT_BINPATH;<filename>/uic</filename>'.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_UICCOM">
-<summary>
-<para>
-Command to generate header files from <filename>.ui</filename> files.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_UICCOMSTR">
-<summary>
-<para>
-The string displayed when generating header files from <filename>.ui</filename> files.
-If this is not set, then &cv-link-QT_UICCOM; (the command line) is displayed.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_UICDECLFLAGS">
-<summary>
-<para>
-Default value is ''. These flags are passed to <command>uic</command>
-when creating a header file from a <filename>.ui</filename> file.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_UICDECLPREFIX">
-<summary>
-<para>
-Default value is <literal>''</literal>.
-Prefix for <command>uic</command> generated header files.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_UICDECLSUFFIX">
-<summary>
-<para>
-Default value is <literal>'.h'</literal>.
-Suffix for <command>uic</command> generated header files.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_UICIMPLFLAGS">
-<summary>
-<para>
-Default value is <literal>''</literal>.
-These flags are passed to <command>uic</command> when creating a C++
-file from a <filename>.ui</filename> file.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_UICIMPLPREFIX">
-<summary>
-<para>
-Default value is <literal>'uic_'</literal>.
-Prefix for uic generated implementation files.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_UICIMPLSUFFIX">
-<summary>
-<para>
-Default value is '&cv-link-CXXFILESUFFIX;'. Suffix for uic generated implementation
-files.
-</para>
-</summary>
-</cvar>
-
-<cvar name="QT_UISUFFIX">
-<summary>
-<para>
-Default value is <literal>'.ui'</literal>.
-Suffix of designer input files.
-</para>
-</summary>
-</cvar>
-
 </sconsdoc>
diff --git a/SCons/Tool/qt3.py b/SCons/Tool/qt3.py
new file mode 100644
index 0000000000..4e6975648f
--- /dev/null
+++ b/SCons/Tool/qt3.py
@@ -0,0 +1,371 @@
+# MIT License
+#
+# Copyright The SCons Foundation
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""Tool-specific initialization for Qt.
+
+There normally shouldn't be any need to import this module directly.
+It will usually be imported through the generic SCons.Tool.Tool()
+selection method.
+"""
+
+import os.path
+import re
+
+import SCons.Action
+import SCons.Builder
+import SCons.Defaults
+import SCons.Scanner
+import SCons.Tool
+import SCons.Util
+import SCons.Tool.cxx
+import SCons.Warnings
+cplusplus = SCons.Tool.cxx
+
+class ToolQtWarning(SCons.Warnings.SConsWarning):
+    pass
+
+class GeneratedMocFileNotIncluded(ToolQtWarning):
+    pass
+
+class QtdirNotFound(ToolQtWarning):
+    pass
+
+SCons.Warnings.enableWarningClass(ToolQtWarning)
+
+header_extensions = [".h", ".hxx", ".hpp", ".hh"]
+if SCons.Util.case_sensitive_suffixes('.h', '.H'):
+    header_extensions.append('.H')
+
+cxx_suffixes = cplusplus.CXXSuffixes
+
+
+def find_platform_specific_qt3_paths():
+    """
+    find non-standard QT paths
+
+    If the platform does not put QT tools in standard search paths,
+    the path is expected to be set using QT3DIR. SCons violates
+    the normal rule of not pulling from the user's environment
+    in this case.  However, some test cases try to validate what
+    happens when QT3DIR is unset, so we need to try to make a guess.
+
+    :return: a guess at a path
+    """
+
+    # qt3_bin_dirs = []
+    qt3_bin_dir = None
+    if os.path.isfile('/etc/redhat-release'):
+        with open('/etc/redhat-release','r') as rr:
+            lines = rr.readlines()
+            distro = lines[0].split()[0]
+        if distro == 'CentOS':
+            # Centos installs QT under /usr/{lib,lib64}/qt{4,5,-3.3}/bin
+            # so we need to handle this differently
+            # qt3_bin_dirs = glob.glob('/usr/lib64/qt*/bin')
+            # TODO: all current Fedoras do the same, need to look deeper here.
+            qt3_bin_dir = '/usr/lib64/qt-3.3/bin'
+
+    return qt3_bin_dir
+
+
+QT3_BIN_DIR = find_platform_specific_qt3_paths()
+
+def checkMocIncluded(target, source, env):
+    moc = target[0]
+    cpp = source[0]
+    # looks like cpp.includes is cleared before the build stage :-(
+    # not really sure about the path transformations (moc.cwd? cpp.cwd?) :-/
+    path = SCons.Defaults.CScan.path(env, moc.cwd)
+    includes = SCons.Defaults.CScan(cpp, env, path)
+    if moc not in includes:
+        SCons.Warnings.warn(
+            GeneratedMocFileNotIncluded,
+            "Generated moc file '%s' is not included by '%s'" %
+            (str(moc), str(cpp)))
+
+def find_file(filename, paths, node_factory):
+    for dir in paths:
+        node = node_factory(filename, dir)
+        if node.rexists():
+            return node
+    return None
+
+class _Automoc:
+    """
+    Callable class, which works as an emitter for Programs, SharedLibraries and
+    StaticLibraries.
+    """
+
+    def __init__(self, objBuilderName):
+        self.objBuilderName = objBuilderName
+
+    def __call__(self, target, source, env):
+        """
+        Smart autoscan function. Gets the list of objects for the Program
+        or Lib. Adds objects and builders for the special qt3 files.
+        """
+        try:
+            if int(env.subst('$QT3_AUTOSCAN')) == 0:
+                return target, source
+        except ValueError:
+            pass
+        try:
+            debug = int(env.subst('$QT3_DEBUG'))
+        except ValueError:
+            debug = 0
+
+        # some shortcuts used in the scanner
+        splitext = SCons.Util.splitext
+        objBuilder = getattr(env, self.objBuilderName)
+
+        # some regular expressions:
+        # Q_OBJECT detection
+        q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]')
+        # cxx and c comment 'eater'
+        #comment = re.compile(r'(//.*)|(/\*(([^*])|(\*[^/]))*\*/)')
+        # CW: something must be wrong with the regexp. See also bug #998222
+        #     CURRENTLY THERE IS NO TEST CASE FOR THAT
+
+        # The following is kind of hacky to get builders working properly (FIXME)
+        objBuilderEnv = objBuilder.env
+        objBuilder.env = env
+        mocBuilderEnv = env.Moc.env
+        env.Moc.env = env
+
+        # make a deep copy for the result; MocH objects will be appended
+        out_sources = source[:]
+
+        for obj in source:
+            if not obj.has_builder():
+                # binary obj file provided
+                if debug:
+                    print("scons: qt3: '%s' seems to be a binary. Discarded." % str(obj))
+                continue
+            cpp = obj.sources[0]
+            if not splitext(str(cpp))[1] in cxx_suffixes:
+                if debug:
+                    print("scons: qt3: '%s' is no cxx file. Discarded." % str(cpp))
+                # c or fortran source
+                continue
+            #cpp_contents = comment.sub('', cpp.get_text_contents())
+            if debug:
+                print("scons: qt3: Getting contents of %s" % cpp)
+            cpp_contents = cpp.get_text_contents()
+            h=None
+            for h_ext in header_extensions:
+                # try to find the header file in the corresponding source
+                # directory
+                hname = splitext(cpp.name)[0] + h_ext
+                h = find_file(hname, (cpp.get_dir(),), env.File)
+                if h:
+                    if debug:
+                        print("scons: qt3: Scanning '%s' (header of '%s')" % (str(h), str(cpp)))
+                    #h_contents = comment.sub('', h.get_text_contents())
+                    h_contents = h.get_text_contents()
+                    break
+            if not h and debug:
+                print("scons: qt3: no header for '%s'." % (str(cpp)))
+            if h and q_object_search.search(h_contents):
+                # h file with the Q_OBJECT macro found -> add moc_cpp
+                moc_cpp = env.Moc(h)
+                moc_o = objBuilder(moc_cpp)
+                out_sources.append(moc_o)
+                #moc_cpp.target_scanner = SCons.Defaults.CScan
+                if debug:
+                    print("scons: qt3: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp)))
+            if cpp and q_object_search.search(cpp_contents):
+                # cpp file with Q_OBJECT macro found -> add moc
+                # (to be included in cpp)
+                moc = env.Moc(cpp)
+                env.Ignore(moc, moc)
+                if debug:
+                    print("scons: qt3: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc)))
+                #moc.source_scanner = SCons.Defaults.CScan
+        # restore the original env attributes (FIXME)
+        objBuilder.env = objBuilderEnv
+        env.Moc.env = mocBuilderEnv
+
+        return (target, out_sources)
+
+AutomocShared = _Automoc('SharedObject')
+AutomocStatic = _Automoc('StaticObject')
+
+def _detect_qt3(env):
+    """Not really safe, but fast method to detect the QT library"""
+
+    QT3DIR = env.get('QT3DIR',None)
+    if not QT3DIR:
+        QT3DIR = os.environ.get('QTDIR',None)
+    if not QT3DIR:
+        moc = env.WhereIs('moc') or env.WhereIs('moc',QT3_BIN_DIR)
+        if moc:
+            QT3DIR = os.path.dirname(os.path.dirname(moc))
+            SCons.Warnings.warn(
+                QtdirNotFound,
+                "Could not detect qt3, using moc executable as a hint (QT3DIR=%s)" % QT3DIR)
+        else:
+            QT3DIR = None
+            SCons.Warnings.warn(
+                QtdirNotFound,
+                "Could not detect qt3, using empty QT3DIR")
+    return QT3DIR
+
+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('$QT3_UICIMPLPREFIX'),
+                                 env.subst('$QT3_UICIMPLSUFFIX')))
+    if len(target) < 3:
+        # third target is moc file
+        target.append(adjustixes(bs,
+                                 env.subst('$QT3_MOCHPREFIX'),
+                                 env.subst('$QT3_MOCHSUFFIX')))
+    return target, source
+
+def uicScannerFunc(node, env, path):
+    lookout = []
+    lookout.extend(env['CPPPATH'])
+    lookout.append(str(node.rfile().dir))
+    includes = re.findall("<include.*?>(.*?)</include>", node.get_text_contents())
+    result = []
+    for incFile in includes:
+        dep = env.FindFile(incFile,lookout)
+        if dep:
+            result.append(dep)
+    return result
+
+uicScanner = SCons.Scanner.ScannerBase(uicScannerFunc,
+                                name = "UicScanner",
+                                node_class = SCons.Node.FS.File,
+                                node_factory = SCons.Node.FS.File,
+                                recursive = 0)
+
+def generate(env):
+    """Add Builders and construction variables for qt3 to an Environment."""
+    CLVar = SCons.Util.CLVar
+    Action = SCons.Action.Action
+    Builder = SCons.Builder.Builder
+
+    qt3path = _detect_qt3(env)
+    if qt3path is None:
+        return None
+
+    env.SetDefault(QT3DIR  = qt3path,
+                   QT3_BINPATH = os.path.join('$QT3DIR', 'bin'),
+                   QT3_CPPPATH = os.path.join('$QT3DIR', 'include'),
+                   QT3_LIBPATH = os.path.join('$QT3DIR', 'lib'),
+                   QT3_MOC = os.path.join('$QT3_BINPATH','moc'),
+                   QT3_UIC = os.path.join('$QT3_BINPATH','uic'),
+                   QT3_LIB = 'qt', # may be set to qt-mt
+
+                   QT3_AUTOSCAN = 1, # scan for moc'able sources
+
+                   # Some QT specific flags. I don't expect someone wants to
+                   # manipulate those ...
+                   QT3_UICIMPLFLAGS = CLVar(''),
+                   QT3_UICDECLFLAGS = CLVar(''),
+                   QT3_MOCFROMHFLAGS = CLVar(''),
+                   QT3_MOCFROMCXXFLAGS = CLVar('-i'),
+
+                   # suffixes/prefixes for the headers / sources to generate
+                   QT3_UICDECLPREFIX = '',
+                   QT3_UICDECLSUFFIX = '.h',
+                   QT3_UICIMPLPREFIX = 'uic_',
+                   QT3_UICIMPLSUFFIX = '$CXXFILESUFFIX',
+                   QT3_MOCHPREFIX = 'moc_',
+                   QT3_MOCHSUFFIX = '$CXXFILESUFFIX',
+                   QT3_MOCCXXPREFIX = '',
+                   QT3_MOCCXXSUFFIX = '.moc',
+                   QT3_UISUFFIX = '.ui',
+
+                   # Commands for the qt3 support ...
+                   # command to generate header, implementation and moc-file
+                   # from a .ui file
+                   QT3_UICCOM = [
+                    CLVar('$QT3_UIC $QT3_UICDECLFLAGS -o ${TARGETS[0]} $SOURCE'),
+                    CLVar('$QT3_UIC $QT3_UICIMPLFLAGS -impl ${TARGETS[0].file} '
+                          '-o ${TARGETS[1]} $SOURCE'),
+                    CLVar('$QT3_MOC $QT3_MOCFROMHFLAGS -o ${TARGETS[2]} ${TARGETS[0]}')],
+                   # command to generate meta object information for a class
+                   # declarated in a header
+                   QT3_MOCFROMHCOM = (
+                          '$QT3_MOC $QT3_MOCFROMHFLAGS -o ${TARGETS[0]} $SOURCE'),
+                   # command to generate meta object information for a class
+                   # declarated in a cpp file
+                   QT3_MOCFROMCXXCOM = [
+                    CLVar('$QT3_MOC $QT3_MOCFROMCXXFLAGS -o ${TARGETS[0]} $SOURCE'),
+                    Action(checkMocIncluded,None)])
+
+    # ... and the corresponding builders
+    uicBld = Builder(action=SCons.Action.Action('$QT3_UICCOM', '$QT3_UICCOMSTR'),
+                     emitter=uicEmitter,
+                     src_suffix='$QT3_UISUFFIX',
+                     suffix='$QT3_UICDECLSUFFIX',
+                     prefix='$QT3_UICDECLPREFIX',
+                     source_scanner=uicScanner)
+    mocBld = Builder(action={}, prefix={}, suffix={})
+    for h in header_extensions:
+        act = SCons.Action.Action('$QT3_MOCFROMHCOM', '$QT3_MOCFROMHCOMSTR')
+        mocBld.add_action(h, act)
+        mocBld.prefix[h] = '$QT3_MOCHPREFIX'
+        mocBld.suffix[h] = '$QT3_MOCHSUFFIX'
+    for cxx in cxx_suffixes:
+        act = SCons.Action.Action('$QT3_MOCFROMCXXCOM', '$QT3_MOCFROMCXXCOMSTR')
+        mocBld.add_action(cxx, act)
+        mocBld.prefix[cxx] = '$QT3_MOCCXXPREFIX'
+        mocBld.suffix[cxx] = '$QT3_MOCCXXSUFFIX'
+
+    # register the builders
+    env['BUILDERS']['Uic'] = uicBld
+    env['BUILDERS']['Moc'] = mocBld
+    static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
+    static_obj.add_src_builder('Uic')
+    shared_obj.add_src_builder('Uic')
+
+    # We use the emitters of Program / StaticLibrary / SharedLibrary
+    # to scan for moc'able files
+    # We can't refer to the builders directly, we have to fetch them
+    # as Environment attributes because that sets them up to be called
+    # correctly later by our emitter.
+    env.AppendUnique(PROGEMITTER =[AutomocStatic],
+                     SHLIBEMITTER=[AutomocShared],
+                     LDMODULEEMITTER=[AutomocShared],
+                     LIBEMITTER  =[AutomocStatic],
+                     # Of course, we need to link against the qt3 libraries
+                     CPPPATH=["$QT3_CPPPATH"],
+                     LIBPATH=["$QT3_LIBPATH"],
+                     LIBS=['$QT3_LIB'])
+
+def exists(env):
+    return _detect_qt3(env)
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/SCons/Tool/qt3.xml b/SCons/Tool/qt3.xml
new file mode 100644
index 0000000000..445751b5ef
--- /dev/null
+++ b/SCons/Tool/qt3.xml
@@ -0,0 +1,527 @@
+<?xml version="1.0"?>
+<!--
+__COPYRIGHT__
+
+This file is processed by the bin/SConsDoc.py module.
+See its __doc__ string for a discussion of the format.
+-->
+
+<!DOCTYPE sconsdoc [
+<!ENTITY % scons SYSTEM '../../doc/scons.mod'>
+%scons;
+<!ENTITY % builders-mod SYSTEM '../../doc/generated/builders.mod'>
+%builders-mod;
+<!ENTITY % functions-mod SYSTEM '../../doc/generated/functions.mod'>
+%functions-mod;
+<!ENTITY % tools-mod SYSTEM '../../doc/generated/tools.mod'>
+%tools-mod;
+<!ENTITY % variables-mod SYSTEM '../../doc/generated/variables.mod'>
+%variables-mod;
+]>
+
+<sconsdoc xmlns="http://www.scons.org/dbxsd/v1.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd">
+
+<tool name="qt3">
+<summary>
+<para>
+Sets &consvars; for building Qt3 applications.
+</para>
+
+<note><para>
+This tool is only suitable for building targeted to Qt3,
+which is obsolete
+(<emphasis>the tool is deprecated since 4.3,
+and was renamed to qt3 in 4.5.0.
+</emphasis>).
+There are contributed tools for Qt4 and Qt5, see
+<ulink url="https://github.com/SCons/scons-contrib">
+https://github.com/SCons/scons-contrib</ulink>.
+Qt4 has also passed end of life for standard support (in Dec 2015).
+</para></note>
+
+<para>
+Note paths for these &consvars; are assembled
+using the <function>os.path.join</function> method
+so they will have the appropriate separator at runtime,
+but are listed here in the various
+entries only with the <literal>'/'</literal> separator
+for simplicity.
+</para>
+
+<para>
+In addition, the &consvars;
+&cv-link-CPPPATH;,
+&cv-link-LIBPATH; and
+&cv-link-LIBS; may be modified
+and the variables
+&cv-link-PROGEMITTER;, &cv-link-SHLIBEMITTER; and &cv-link-LIBEMITTER;
+are modified. Because the build-performance is affected when using this tool,
+you have to explicitly specify it at Environment creation:
+</para>
+
+<example_commands>
+Environment(tools=['default','qt3'])
+</example_commands>
+
+<para>
+The &t-qt3; tool supports the following operations:
+</para>
+
+<para>
+<emphasis role="strong">Automatic moc file generation from header files.</emphasis>
+You do not have to specify moc files explicitly, the tool does it for you.
+However, there are a few preconditions to do so: Your header file must have
+the same filebase as your implementation file and must stay in the same
+directory. It must have one of the suffixes
+<filename>.h</filename>,
+<filename>.hpp</filename>,
+<filename>.H</filename>,
+<filename>.hxx</filename>,
+<filename>.hh</filename>.
+You can turn off automatic moc file generation by setting
+&cv-link-QT3_AUTOSCAN; to <constant>False</constant>.
+See also the corresponding
+&b-link-Moc; Builder.
+</para>
+
+<para>
+<emphasis role="strong">Automatic moc file generation from C++ files.</emphasis>
+As described in the Qt documentation, include the moc file at the end of
+the C++ file. Note that you have to include the file, which is generated
+by the transformation
+<literal>${QT3_MOCCXXPREFIX}&lt;basename&gt;${QT3_MOCCXXSUFFIX}</literal>, by default
+<filename>&lt;basename&gt;.mo</filename>. A warning is generated after building the moc file if you
+do not include the correct file. If you are using &f-link-VariantDir;, you may
+need to specify <parameter>duplicate=True</parameter>.
+You can turn off automatic moc file generation by setting &cv-QT3_AUTOSCAN; to
+<literal>False</literal>. See also the corresponding
+&b-link-Moc; Builder.
+</para>
+
+<para>
+<emphasis role="strong">Automatic handling of .ui files.</emphasis>
+The implementation files generated from <filename>.ui</filename>
+files are handled much the same as yacc or lex files.
+Each <command>.ui</command> file given as a source of &b-link-Program;,
+&b-link-Library; or &b-link-SharedLibrary;
+will generate three files: the declaration file, the
+implementation file and a moc file. Because there are also generated headers,
+you may need to specify <parameter>duplicate=True</parameter> in calls to
+&f-link-VariantDir;.
+See also the corresponding
+&b-link-Uic; Builder.
+</para>
+</summary>
+<sets>
+<item>QT3DIR</item>
+<item>QT3_BINPATH</item>
+<item>QT3_CPPPATH</item>
+<item>QT3_LIBPATH</item>
+<item>QT3_MOC</item>
+<item>QT3_UIC</item>
+<item>QT3_LIB</item>
+<item>QT3_AUTOSCAN</item>
+<item>QT3_UICIMPLFLAGS</item>
+<item>QT3_UICDECLFLAGS</item>
+<item>QT3_MOCFROMHFLAGS</item>
+<item>QT3_MOCFROMCXXFLAGS</item>
+<item>QT3_UICDECLPREFIX</item>
+<item>QT3_UICDECLSUFFIX</item>
+<item>QT3_UICIMPLPREFIX</item>
+<item>QT3_UICIMPLSUFFIX</item>
+<item>QT3_MOCHPREFIX</item>
+<item>QT3_MOCHSUFFIX</item>
+<item>QT3_MOCCXXPREFIX</item>
+<item>QT3_MOCCXXSUFFIX</item>
+<item>QT3_UISUFFIX</item>
+<item>QT3_UICCOM</item>
+<item>QT3_MOCFROMHCOM</item>
+<item>QT3_MOCFROMCXXCOM</item>
+</sets>
+<uses>
+<item>QT3DIR</item>
+</uses>
+</tool>
+
+<builder name="Moc">
+<summary>
+<para>
+Builds an output file from a <command>moc</command> input file.
+<command>moc</command> input files are either header files or C++ files.
+This builder is only available after using the
+tool &t-link-qt3;. See the &cv-link-QT3DIR; variable for more information.
+Example:
+</para>
+
+<example_commands>
+env.Moc('foo.h')  # generates moc_foo.cc
+env.Moc('foo.cpp')  # generates foo.moc
+</example_commands>
+</summary>
+</builder>
+
+<builder name="Uic">
+<summary>
+<para>
+Builds a header file, an implementation file and a moc file from an ui file.
+and returns the corresponding nodes in the that order.
+This builder is only available after using the tool &t-link-qt3;.
+Note: you can specify <filename>.ui</filename> files directly as source
+files to the &b-link-Program;,
+&b-link-Library; and &b-link-SharedLibrary; builders
+without using this builder. Using this builder lets you override the standard
+naming conventions (be careful: prefixes are always prepended to names of
+built files; if you don't want prefixes, you may set them to ``).
+See the &cv-link-QT3DIR; variable for more information.
+Example:
+</para>
+
+<example_commands>
+env.Uic('foo.ui')  # -> ['foo.h', 'uic_foo.cc', 'moc_foo.cc']
+env.Uic(
+    target=Split('include/foo.h gen/uicfoo.cc gen/mocfoo.cc'),
+    source='foo.ui'
+)  # -> ['include/foo.h', 'gen/uicfoo.cc', 'gen/mocfoo.cc']
+</example_commands>
+</summary>
+</builder>
+
+<cvar name="QT3DIR">
+<summary>
+<para>
+The path to the Qt installation to build against.
+If not already set,
+&t-link-qt3; tool tries to obtain this from
+<varname>os.environ</varname>;
+if not found there, it tries to make a guess.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QTDIR.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_AUTOSCAN">
+<summary>
+<para>
+Turn off scanning for mocable files. Use the &b-link-Moc; Builder to explicitly
+specify files to run <command>moc</command> on.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_AUTOSCAN.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_BINPATH">
+<summary>
+<para>
+The path where the Qt binaries are installed.
+The default value is '&cv-link-QT3DIR;<filename>/bin</filename>'.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_BINPATH.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_CPPPATH">
+<summary>
+<para>
+The path where the Qt header files are installed.
+The default value is '&cv-link-QT3DIR;/include'.
+Note: If you set this variable to <constant>None</constant>,
+the tool won't change the &cv-link-CPPPATH;
+construction variable.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_CPPPATH.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_DEBUG">
+<summary>
+<para>
+Prints lots of debugging information while scanning for moc files.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_DEBUG.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_LIB">
+<summary>
+<para>
+Default value is <literal>'qt'</literal>.
+You may want to set this to <literal>'qt-mt'</literal>.
+Note: If you set this variable to <constant>None</constant>,
+the tool won't change the &cv-link-LIBS; variable.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_LIB.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_LIBPATH">
+<summary>
+<para>
+The path where the Qt libraries are installed.
+The default value is '&cv-link-QT3DIR;<filename>/lib</filename>'.
+Note: If you set this variable to <constant>None</constant>,
+the tool won't change the &cv-link-LIBPATH;
+construction variable.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_LIBPATH.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_MOC">
+<summary>
+<para>
+Default value is '&cv-link-QT3_BINPATH;<filename>/moc</filename>'.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_MOCCXXPREFIX">
+<summary>
+<para>
+Default value is <literal>''</literal>.
+Prefix for <command>moc</command> output files when source is a C++ file.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_MOCCXXSUFFIX">
+<summary>
+<para>
+Default value is <literal>'.moc'</literal>.
+Suffix for <command>moc</command> output files when source is a C++ file.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_MOCCXXSUFFIX.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_MOCFROMCXXFLAGS">
+<summary>
+<para>
+Default value is <literal>'-i'</literal>.
+These flags are passed to <command>moc</command> when moccing a C++ file.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_MOCFROMCXXFLAGS.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_MOCFROMCXXCOM">
+<summary>
+<para>
+Command to generate a moc file from a C++ file.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_MOCFROMCXXCOM.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_MOCFROMCXXCOMSTR">
+<summary>
+<para>
+The string displayed when generating a moc file from a C++ file.
+If this is not set, then &cv-link-QT3_MOCFROMCXXCOM; (the command line) is displayed.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_MOCFROMCXXCOMSTR.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_MOCFROMHCOM">
+<summary>
+<para>
+Command to generate a moc file from a header.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_MOCFROMSHCOM.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_MOCFROMHCOMSTR">
+<summary>
+<para>
+The string displayed when generating a moc file from a C++ file.
+If this is not set, then &cv-link-QT3_MOCFROMHCOM; (the command line) is displayed.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_MOCFROMSHCOMSTR.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_MOCFROMHFLAGS">
+<summary>
+<para>
+Default value is <literal>''</literal>. These flags are passed to <command>moc</command>
+when moccing a header file.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_MOCFROMSHFLAGS.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_MOCHPREFIX">
+<summary>
+<para>
+Default value is <literal>'moc_'</literal>.
+Prefix for <command>moc</command> output files when source is a header.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_MOCHPREFIX.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_MOCHSUFFIX">
+<summary>
+<para>
+Default value is '&cv-link-CXXFILESUFFIX;'.
+Suffix for moc output files when source is a header.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_MOCHSUFFIX.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_UIC">
+<summary>
+<para>
+Default value is '&cv-link-QT3_BINPATH;<filename>/uic</filename>'.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_UIC.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_UICCOM">
+<summary>
+<para>
+Command to generate header files from <filename>.ui</filename> files.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_UICCOM.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_UICCOMSTR">
+<summary>
+<para>
+The string displayed when generating header files from <filename>.ui</filename> files.
+If this is not set, then &cv-link-QT3_UICCOM; (the command line) is displayed.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_UICCOMSTR.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_UICDECLFLAGS">
+<summary>
+<para>
+Default value is ''. These flags are passed to <command>uic</command>
+when creating a header file from a <filename>.ui</filename> file.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_UICDECLFLAGS.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_UICDECLPREFIX">
+<summary>
+<para>
+Default value is <literal>''</literal>.
+Prefix for <command>uic</command> generated header files.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_UICDECLPREFIX.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_UICDECLSUFFIX">
+<summary>
+<para>
+Default value is <literal>'.h'</literal>.
+Suffix for <command>uic</command> generated header files.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_UICDECLSUFFIX.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_UICIMPLFLAGS">
+<summary>
+<para>
+Default value is <literal>''</literal>.
+These flags are passed to <command>uic</command> when creating a C++
+file from a <filename>.ui</filename> file.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_UICIMPFLAGS.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_UICIMPLPREFIX">
+<summary>
+<para>
+Default value is <literal>'uic_'</literal>.
+Prefix for uic generated implementation files.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_UICIMPLPREFIX.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_UICIMPLSUFFIX">
+<summary>
+<para>
+Default value is '&cv-link-CXXFILESUFFIX;'. Suffix for uic generated implementation
+files.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_UICIMPLSUFFIX.
+</para>
+</summary>
+</cvar>
+
+<cvar name="QT3_UISUFFIX">
+<summary>
+<para>
+Default value is <literal>'.ui'</literal>.
+Suffix of designer input files.
+</para>
+<para>
+<emphasis>Changed in 4.5.0</emphasis>: renamed from QT_UISUFFIX.
+</para>
+</summary>
+</cvar>
+
+</sconsdoc>
diff --git a/SCons/Warnings.py b/SCons/Warnings.py
index 754f05d860..f77a24a2d7 100644
--- a/SCons/Warnings.py
+++ b/SCons/Warnings.py
@@ -131,7 +131,7 @@ class DeprecatedDebugOptionsWarning(MandatoryDeprecatedWarning):
 class DeprecatedMissingSConscriptWarning(DeprecatedWarning):
     pass
 
-class ToolQtDeprecatedWarning(FutureDeprecatedWarning):
+class ToolQtDeprecatedWarning(DeprecatedWarning):
     pass
 
 # The below is a list of 2-tuples.  The first element is a class object.


Test patch:
diff --git a/test/QT/CPPPATH-appended.py b/test/QT/qt3/CPPPATH-appended.py
similarity index 100%
rename from test/QT/CPPPATH-appended.py
rename to test/QT/qt3/CPPPATH-appended.py
diff --git a/test/QT/CPPPATH.py b/test/QT/qt3/CPPPATH.py
similarity index 100%
rename from test/QT/CPPPATH.py
rename to test/QT/qt3/CPPPATH.py
diff --git a/test/QT/QTFLAGS.py b/test/QT/qt3/QTFLAGS.py
similarity index 73%
rename from test/QT/QTFLAGS.py
rename to test/QT/qt3/QTFLAGS.py
index c759c2a4ad..56536845f3 100644
--- a/test/QT/QTFLAGS.py
+++ b/test/QT/qt3/QTFLAGS.py
@@ -24,7 +24,7 @@
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 """
-Testing the configuration mechanisms of the 'qt' tool.
+Testing the configuration mechanisms of the 'qt3' tool.
 """
 
 import TestSCons
@@ -39,24 +39,24 @@
 
 test.run(
     chdir=test.workpath('qt', 'lib'),
-    arguments="--warn=no-tool-qt-deprecated .",
+    arguments=".",
     stderr=TestSCons.noisy_ar,
     match=TestSCons.match_re_dotall,
 )
 
-QT = test.workpath('qt')
-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'))
+QT3 = test.workpath('qt')
+QT3_LIB = 'myqt'
+QT3_MOC = '%s %s' % (_python_, test.workpath('qt', 'bin', 'mymoc.py'))
+QT3_UIC = '%s %s' % (_python_, test.workpath('qt', 'bin', 'myuic.py'))
 
 def createSConstruct(test, place, overrides):
     test.write(place, """\
 env = Environment(
-    tools=['default','qt'],
-    QTDIR = r'%s',
-    QT_LIB = r'%s',
-    QT_MOC = r'%s',
-    QT_UIC = r'%s',
+    tools=['default','qt3'],
+    QT3DIR = r'%s',
+    QT3_LIB = r'%s',
+    QT3_MOC = r'%s',
+    QT3_UIC = r'%s',
     %s  # last because 'overrides' may add comma
 )
 if ARGUMENTS.get('variant_dir', 0):
@@ -70,23 +70,23 @@ def createSConstruct(test, place, overrides):
     sconscript = File('SConscript')
 Export("env")
 SConscript(sconscript)
-""" % (QT, QT_LIB, QT_MOC, QT_UIC, overrides))
+""" % (QT3, QT3_LIB, QT3_MOC, QT3_UIC, overrides))
 
 
 createSConstruct(test, ['work1', 'SConstruct'],
-                 """QT_UICIMPLFLAGS='-x',
-                    QT_UICDECLFLAGS='-y',
-                    QT_MOCFROMHFLAGS='-z',
-                    QT_MOCFROMCXXFLAGS='-i -w',
-                    QT_UICDECLPREFIX='uic-',
-                    QT_UICDECLSUFFIX='.hpp',
-                    QT_UICIMPLPREFIX='',
-                    QT_UICIMPLSUFFIX='.cxx',
-                    QT_MOCHPREFIX='mmm',
-                    QT_MOCHSUFFIX='.cxx',
-                    QT_MOCCXXPREFIX='moc',
-                    QT_MOCCXXSUFFIX='.inl',
-                    QT_UISUFFIX='.myui',""")
+                 """QT3_UICIMPLFLAGS='-x',
+                    QT3_UICDECLFLAGS='-y',
+                    QT3_MOCFROMHFLAGS='-z',
+                    QT3_MOCFROMCXXFLAGS='-i -w',
+                    QT3_UICDECLPREFIX='uic-',
+                    QT3_UICDECLSUFFIX='.hpp',
+                    QT3_UICIMPLPREFIX='',
+                    QT3_UICIMPLSUFFIX='.cxx',
+                    QT3_MOCHPREFIX='mmm',
+                    QT3_MOCHSUFFIX='.cxx',
+                    QT3_MOCCXXPREFIX='moc',
+                    QT3_MOCCXXSUFFIX='.inl',
+                    QT3_UISUFFIX='.myui',""")
 test.write(['work1', 'SConscript'],"""
 Import("env")
 env.Program('mytest', ['mocFromH.cpp',
@@ -137,7 +137,7 @@ def createSConstruct(test, place, overrides):
 }
 """)
 
-test.run(chdir='work1', arguments="--warn=no-tool-qt-deprecated mytest" + _exe)
+test.run(chdir='work1', arguments="mytest" + _exe)
 
 test.must_exist(
     ['work1', 'mmmmocFromH.cxx'],
@@ -173,32 +173,32 @@ def _flagTest(test,fileToContentsStart):
 import os.path
 
 env1 = Environment(
-    tools=['qt'],
-    QTDIR=r'%(QTDIR)s',
-    QT_BINPATH='$QTDIR/bin64',
-    QT_LIBPATH='$QTDIR/lib64',
-    QT_CPPPATH='$QTDIR/h64',
+    tools=['qt3'],
+    QT3DIR=r'%(QT3DIR)s',
+    QT3_BINPATH='$QT3DIR/bin64',
+    QT3_LIBPATH='$QT3DIR/lib64',
+    QT3_CPPPATH='$QT3DIR/h64',
 )
 
 cpppath = env1.subst('$CPPPATH')
-if os.path.normpath(cpppath) != os.path.join(r'%(QTDIR)s', 'h64'):
+if os.path.normpath(cpppath) != os.path.join(r'%(QT3DIR)s', 'h64'):
     print(cpppath)
     Exit(1)
 libpath = env1.subst('$LIBPATH')
-if os.path.normpath(libpath) != os.path.join(r'%(QTDIR)s', 'lib64'):
+if os.path.normpath(libpath) != os.path.join(r'%(QT3DIR)s', 'lib64'):
     print(libpath)
     Exit(2)
-qt_moc = env1.subst('$QT_MOC')
-if os.path.normpath(qt_moc) != os.path.join(r'%(QTDIR)s', 'bin64', 'moc'):
+qt_moc = env1.subst('$QT3_MOC')
+if os.path.normpath(qt_moc) != os.path.join(r'%(QT3DIR)s', 'bin64', 'moc'):
     print(qt_moc)
     Exit(3)
 
 env2 = Environment(
-    tools=['default', 'qt'], QTDIR=None, QT_LIB=None, QT_CPPPATH=None, QT_LIBPATH=None
+    tools=['default', 'qt3'], QT3DIR=None, QT3_LIB=None, QT3_CPPPATH=None, QT3_LIBPATH=None
 )
 
 env2.Program('main.cpp')
-""" % {'QTDIR':QT})
+""" % {'QT3DIR':QT3})
 
 test.write(['work2', 'main.cpp'], """
 int main(void) { return 0; }
@@ -206,7 +206,7 @@ def _flagTest(test,fileToContentsStart):
 
 # Ignore stderr, because if Qt is not installed,
 # there may be a warning about an empty QTDIR on stderr.
-test.run(arguments="--warn=no-tool-qt-deprecated", chdir='work2', stderr=None)
+test.run(chdir='work2', stderr=None)
 
 test.must_exist(['work2', 'main' + _exe])
 
diff --git a/test/QT/Tool.py b/test/QT/qt3/Tool.py
similarity index 94%
rename from test/QT/Tool.py
rename to test/QT/qt3/Tool.py
index 122e7f4136..1b34ea2ab9 100644
--- a/test/QT/Tool.py
+++ b/test/QT/qt3/Tool.py
@@ -24,7 +24,7 @@
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 """
-Verify that applying env.Tool('qt') after running Configure checks
+Verify that applying env.Tool('qt3') after running Configure checks
 works properly.  This was broken in 0.96.95.
 
 The configuration here is a moderately stripped-down version of the
@@ -90,7 +90,7 @@ def CheckForQt(context):
     ]
 
   if 'QTDIR' in os.environ:
-    potential_qt_dirs.insert(0, os.environ[ 'QTDIR' ])
+    potential_qt_dirs.insert(0, os.environ['QTDIR'])
   
   if env[ 'qt_directory' ] != "/":
      uic_path = os.path.join(env['qt_directory'], 'bin', 'uic')
@@ -101,7 +101,7 @@ def CheckForQt(context):
         return 0
 
   for i in potential_qt_dirs:
-    context.env.Replace(QTDIR = i)
+    context.env.Replace(QT3DIR = i)
     if CheckForQtAt(context, i):
        # additional checks to validate QT installation
        if not os.path.isfile(os.path.join(i, 'bin', 'uic')):
@@ -133,7 +133,7 @@ def AttemptLinkWithVariables(context, variables, code, extension, prefix):
 opts.Add(PathVariable("qt_directory", "Path to Qt directory", "/"))
 opts.Update(env)
 
-env['QT_LIB'] = 'qt-mt'
+env['QT3_LIB'] = 'qt-mt'
 config = env.Configure(custom_tests = {
     'CheckForQt' : CheckForQt,
 })
@@ -142,10 +142,10 @@ def AttemptLinkWithVariables(context, variables, code, extension, prefix):
     print("Failed to find valid QT environment.")
     Exit(1)
 
-env.Tool('qt', ['$TOOL_PATH'])
+env.Tool('qt3', ['$TOOL_PATH'])
 """)
 
-test.run(arguments='--warn=no-tool-qt-deprecated .')
+test.run(arguments='.')
 
 test.pass_test()
 
diff --git a/test/QT/copied-env.py b/test/QT/qt3/copied-env.py
similarity index 96%
rename from test/QT/copied-env.py
rename to test/QT/qt3/copied-env.py
index 74f59b7fc2..9bcb95b68d 100644
--- a/test/QT/copied-env.py
+++ b/test/QT/qt3/copied-env.py
@@ -33,7 +33,7 @@
 
 test.Qt_dummy_installation()
 
-test.Qt_create_SConstruct('SConstruct')
+test.Qt_create_SConstruct('SConstruct', qt_tool='qt3')
 
 test.write('SConscript', """\
 Import("env")
@@ -63,7 +63,7 @@
 void aaa(void)
 """)
 
-test.run(arguments="--warn=no-tool-qt-deprecated")
+test.run()
 
 moc_MyForm = [x for x in test.stdout().split('\n') if x.find('moc_MyForm') != -1]
 
diff --git a/test/QT/empty-env.py b/test/QT/qt3/empty-env.py
similarity index 88%
rename from test/QT/empty-env.py
rename to test/QT/qt3/empty-env.py
index e9dfc81b1e..cd14340804 100644
--- a/test/QT/empty-env.py
+++ b/test/QT/qt3/empty-env.py
@@ -35,11 +35,11 @@
 
 test.write('SConstruct', """\
 orig = Environment()
-env = orig.Clone(QTDIR = r'%s',
-                 QT_LIB = r'%s',
-                 QT_MOC = r'%s',
-                 QT_UIC = r'%s',
-                 tools=['qt'])
+env = orig.Clone(QT3DIR = r'%s',
+                 QT3_LIB = r'%s',
+                 QT3_MOC = r'%s',
+                 QT3_UIC = r'%s',
+                 tools=['qt3'])
 env.Program('main', 'main.cpp', CPPDEFINES=['FOO'], LIBS=[])
 """ % (test.QT, test.QT_LIB, test.QT_MOC, test.QT_UIC))
 
@@ -61,11 +61,10 @@
 
 # we can receive warnings about a non detected qt (empty QTDIR)
 # these are not critical, but may be annoying.
-test.run(stderr=None, arguments='--warn=no-tool-qt-deprecated')
+test.run(stderr=None)
 
 test.run(
     program=test.workpath('main' + TestSCons._exe),
-    arguments='--warn=no-tool-qt-deprecated',
     stderr=None,
     stdout='qt/include/foo6.h\n',
 )
diff --git a/test/QT/generated-ui.py b/test/QT/qt3/generated-ui.py
similarity index 95%
rename from test/QT/generated-ui.py
rename to test/QT/qt3/generated-ui.py
index fd368b34d3..d43b21b000 100644
--- a/test/QT/generated-ui.py
+++ b/test/QT/qt3/generated-ui.py
@@ -45,7 +45,7 @@
 import os
 aa=os.getcwd()
 
-env=Environment(tools=['default','expheaders','qt'],toolpath=[aa])
+env=Environment(tools=['default','expheaders','qt3'],toolpath=[aa])
 if 'HOME' in os.environ:
     env['ENV']['HOME'] = os.environ['HOME']
 env["EXP_HEADER_ABS"]=os.path.join(os.getcwd(),'include')
@@ -120,12 +120,11 @@ def exists(env):
 """)
 
 test.run(
-    arguments='--warn=no-tool-qt-deprecated',
     stderr=TestSCons.noisy_ar,
     match=TestSCons.match_re_dotall,
 )
 
-test.up_to_date(options="--warn=no-tool-qt-deprecated", arguments=".")
+test.up_to_date(arguments=".")
 
 test.pass_test()
 
diff --git a/test/QT/installed.py b/test/QT/qt3/installed.py
similarity index 91%
rename from test/QT/installed.py
rename to test/QT/qt3/installed.py
index 9e8693e3f6..71ff98fb70 100644
--- a/test/QT/installed.py
+++ b/test/QT/qt3/installed.py
@@ -24,7 +24,7 @@
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 """
-Look if qt is installed, and try out all builders.
+Look if qt3 is installed, and try out all builders.
 """
 
 import os
@@ -56,7 +56,7 @@
 except KeyError:
     ENV_PATH=ENV.get('PATH', '')
 
-env = Environment(tools=['default','qt'],
+env = Environment(tools=['default','qt3'],
                   ENV={'PATH':ENV_PATH,
                        'PATHEXT':os.environ.get('PATHEXT'),
                        'HOME':os.getcwd(),
@@ -65,9 +65,9 @@
                   CXXFILESUFFIX=".cpp")
 
 conf = env.Configure()
-if not conf.CheckLib(env.subst("$QT_LIB"), autoadd=0):
-    conf.env['QT_LIB'] = 'qt-mt'
-    if not conf.CheckLib(env.subst("$QT_LIB"), autoadd=0):
+if not conf.CheckLib(env.subst("$QT3_LIB"), autoadd=0):
+    conf.env['QT3_LIB'] = 'qt-mt'
+    if not conf.CheckLib(env.subst("$QT3_LIB"), autoadd=0):
          Exit(0)
 env = conf.Finish()
 VariantDir('bld', '.')
@@ -196,18 +196,18 @@ class MyClass2 : public QObject {
         sys.stdout.write('test_realqt returned status %s\n' % test.status)
         test.fail_test()
 
-QTDIR = os.environ['QTDIR']
+QT3DIR = os.environ['QTDIR']
 PATH = os.environ['PATH']
 os.environ['QTDIR'] = ''
 os.environ['PATH'] = '.'
 
 test.run(
     stderr=None,
-    arguments="--warn=no-tool-qt-deprecated -c bld/test_realqt" + TestSCons._exe,
+    arguments="-c bld/test_realqt" + TestSCons._exe,
 )
 
-expect1 = "scons: warning: Could not detect qt, using empty QTDIR"
-expect2 = "scons: warning: Could not detect qt, using moc executable as a hint"
+expect1 = "scons: warning: Could not detect qt3, using empty QT3DIR"
+expect2 = "scons: warning: Could not detect qt3, using moc executable as a hint"
 
 test.fail_test(expect1 not in test.stderr() and expect2 not in test.stderr())
 
diff --git a/test/QT/manual.py b/test/QT/qt3/manual.py
similarity index 95%
rename from test/QT/manual.py
rename to test/QT/qt3/manual.py
index 84c6df8e04..f467b5ae2c 100644
--- a/test/QT/manual.py
+++ b/test/QT/qt3/manual.py
@@ -24,7 +24,7 @@
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 """
-Test the manual QT builder calls.
+Test the manual QT3 builder calls.
 """
 
 import TestSCons
@@ -51,7 +51,7 @@
 
 # manual target specification
 sources.append(env.Moc('moc-ddd.cpp', 'include/ddd.h',
-               QT_MOCHPREFIX='')) # Watch out !
+               QT3_MOCHPREFIX='')) # Watch out !
 moc = env.Moc('moc_eee.cpp', 'eee.cpp')
 env.Ignore( moc, moc )
 sources.extend(env.Uic(['include/uic_fff.hpp', 'fff.cpp', 'fff.moc.cpp'],
@@ -61,7 +61,7 @@
 env.Program(target='aaa',
             source=sources,
             CPPPATH=['$CPPPATH', './include'],
-            QT_AUTOSCAN=0)
+            QT3_AUTOSCAN=0)
 """)
 
 test.write('aaa.cpp', r"""
@@ -123,7 +123,7 @@
 }
 """)
 
-test.run(arguments="--warn=no-tool-qt-deprecated " + aaa_exe)
+test.run(arguments=aaa_exe)
 
 # normal invocation
 test.must_exist(test.workpath('include', 'moc_aaa.cc'))
diff --git a/test/QT/moc-from-cpp.py b/test/QT/qt3/moc-from-cpp.py
similarity index 100%
rename from test/QT/moc-from-cpp.py
rename to test/QT/qt3/moc-from-cpp.py
diff --git a/test/QT/moc-from-header.py b/test/QT/qt3/moc-from-header.py
similarity index 100%
rename from test/QT/moc-from-header.py
rename to test/QT/qt3/moc-from-header.py
diff --git a/test/QT/qt_warnings.py b/test/QT/qt3/qt_warnings.py
similarity index 89%
rename from test/QT/qt_warnings.py
rename to test/QT/qt3/qt_warnings.py
index fb23a71511..1cbf2b0138 100644
--- a/test/QT/qt_warnings.py
+++ b/test/QT/qt3/qt_warnings.py
@@ -51,7 +51,7 @@
 env.StaticLibrary('aaa.cpp')
 """)
 
-test.run(arguments="--warn=no-tool-qt-deprecated", stderr=None)
+test.run(stderr=None)
 
 match12 = r"""
 scons: warning: Generated moc file 'aaa.moc' is not included by 'aaa.cpp'
@@ -64,7 +64,7 @@
 
 os.environ['QTDIR'] = test.QT
 
-test.run(arguments='--warn=no-tool-qt-deprecated -n noqtdir=1')
+test.run(arguments='-n noqtdir=1')
 
 # We'd like to eliminate $QTDIR from the environment as follows:
 #       del os.environ['QTDIR']
@@ -74,7 +74,7 @@
 # environment, so it only gets removed from the Python dictionary.
 # Consequently, we need to just wipe out its value as follows>
 os.environ['QTDIR'] = ''
-test.run(stderr=None, arguments='--warn=no-tool-qt-deprecated -n noqtdir=1')
+test.run(stderr=None, arguments='-n noqtdir=1')
 
 moc = test.where_is('moc')
 if moc:
@@ -83,13 +83,13 @@
     qtdir = qtdir.replace('\\', '\\\\' )
 
     expect = r"""
-scons: warning: Could not detect qt, using moc executable as a hint \(QTDIR=%s\)
+scons: warning: Could not detect qt3, using moc executable as a hint \(QT3DIR=%s\)
 File "%s", line \d+, in (\?|<module>)
 """ % (qtdir, re.escape(SConstruct_path))
 else:
 
     expect = r"""
-scons: warning: Could not detect qt, using empty QTDIR
+scons: warning: Could not detect qt3, using empty QT3DIR
 File "%s", line \d+, in (\?|<module>)
 """ % re.escape(SConstruct_path)
 
diff --git a/test/QT/reentrant.py b/test/QT/qt3/reentrant.py
similarity index 98%
rename from test/QT/reentrant.py
rename to test/QT/qt3/reentrant.py
index 40fb1f19ae..be6d8a62f5 100644
--- a/test/QT/reentrant.py
+++ b/test/QT/qt3/reentrant.py
@@ -49,7 +49,7 @@
 
 test.write('SConscript', """\
 Import("env")
-env = env.Clone(tools=['qt'])
+env = env.Clone(tools=['qt3'])
 env.Program('main', 'main.cpp', CPPDEFINES=['FOO'], LIBS=[])
 """)
 
diff --git a/test/QT/source-from-ui.py b/test/QT/qt3/source-from-ui.py
similarity index 76%
rename from test/QT/source-from-ui.py
rename to test/QT/qt3/source-from-ui.py
index 569fbab2cf..1404f75328 100644
--- a/test/QT/source-from-ui.py
+++ b/test/QT/qt3/source-from-ui.py
@@ -67,9 +67,9 @@
 }
 """)
 
-test.run(arguments="--warn=no-tool-qt-deprecated " + aaa_dll)
+test.run(arguments=aaa_dll)
 
-test.up_to_date(options='--warn=no-tool-qt-deprecated -n', arguments=aaa_dll)
+test.up_to_date(options='-n', arguments=aaa_dll)
 
 test.write('aaa.ui', r"""
 /* a change */
@@ -81,11 +81,11 @@
 DLLEXPORT void aaa(void)
 """)
 
-test.not_up_to_date(options='--warn=no-tool-qt-deprecated -n', arguments=moc)
-test.not_up_to_date(options='--warn=no-tool-qt-deprecated -n', arguments=cpp)
-test.not_up_to_date(options='--warn=no-tool-qt-deprecated -n', arguments=h)
+test.not_up_to_date(options='-n', arguments=moc)
+test.not_up_to_date(options='-n', arguments=cpp)
+test.not_up_to_date(options='-n', arguments=h)
 
-test.run(arguments="--warn=no-tool-qt-deprecated " + aaa_dll)
+test.run(arguments=" " + aaa_dll)
 
 test.write('aaa.ui', r"""
 void aaa(void)
@@ -93,28 +93,28 @@
 """)
 
 # test that non-existant ui.h files are ignored (as uic does)
-test.run(arguments="--warn=no-tool-qt-deprecated " + aaa_dll)
+test.run(arguments=" " + aaa_dll)
 
 test.write('aaa.ui.h', r"""
 /* test dependency to .ui.h */
 """)
 
-test.run(arguments="--warn=no-tool-qt-deprecated " + aaa_dll)
+test.run(arguments=" " + aaa_dll)
 
 test.write('aaa.ui.h', r"""
 /* changed */
 """)
 
-test.not_up_to_date(options='--warn=no-tool-qt-deprecated -n', arguments=obj)
-test.not_up_to_date(options='--warn=no-tool-qt-deprecated -n', arguments=cpp)
-test.not_up_to_date(options='--warn=no-tool-qt-deprecated -n', arguments=h)
-test.not_up_to_date(options='--warn=no-tool-qt-deprecated -n', arguments=moc)
+test.not_up_to_date(options='-n', arguments=obj)
+test.not_up_to_date(options='-n', arguments=cpp)
+test.not_up_to_date(options='-n', arguments=h)
+test.not_up_to_date(options='-n', arguments=moc)
 
 # clean up
-test.run(arguments="--warn=no-tool-qt-deprecated -c " + aaa_dll)
+test.run(arguments=" -c " + aaa_dll)
 
 test.run(
-    arguments="--warn=no-tool-qt-deprecated variant_dir=1 "
+    arguments="variant_dir=1 "
     + test.workpath('build', aaa_dll)
 )
 
@@ -129,7 +129,7 @@
 test.fail_test(cppContents.find('#include "aaa.ui.h"') == -1)
 
 test.run(
-    arguments="--warn=no-tool-qt-deprecated variant_dir=1 chdir=1 "
+    arguments="variant_dir=1 chdir=1 "
     + test.workpath('build', aaa_dll)
 )
 
@@ -141,7 +141,7 @@
 test.must_not_exist(test.workpath(h))
 
 test.run(
-    arguments="--warn=no-tool-qt-deprecated variant_dir=1 chdir=1 dup=0 "
+    arguments=" variant_dir=1 chdir=1 dup=0 "
     + test.workpath('build_dup0', aaa_dll)
 )
 
diff --git a/test/QT/up-to-date.py b/test/QT/qt3/up-to-date.py
similarity index 98%
rename from test/QT/up-to-date.py
rename to test/QT/qt3/up-to-date.py
index 06fb5590ea..ec51238279 100644
--- a/test/QT/up-to-date.py
+++ b/test/QT/qt3/up-to-date.py
@@ -53,7 +53,7 @@
 import os
 aa=os.getcwd()
 
-env=Environment(tools=['default','expheaders','qt'],toolpath=[aa])
+env=Environment(tools=['default','expheaders','qt3'],toolpath=[aa])
 env["EXP_HEADER_ABS"]=os.path.join(os.getcwd(),'include')
 if not os.access(env["EXP_HEADER_ABS"],os.F_OK):
    os.mkdir (env["EXP_HEADER_ABS"])
diff --git a/test/import.py b/test/import.py
index 55a40cc43b..50d7b2178c 100644
--- a/test/import.py
+++ b/test/import.py
@@ -128,23 +128,26 @@
     import os.path
 
     qtdir = os.path.dirname(os.path.dirname(moc))
-
-    qt_err = r"""
-scons: warning: Could not detect qt, using moc executable as a hint \(QTDIR=%(qtdir)s\)
-""" % locals()
-
+    qt3_err = fr"""
+scons: warning: Could not detect qt3, using moc executable as a hint \(QT3DIR={qtdir}\)
+"""
 else:
+    qt3_err = r"""
+scons: warning: Could not detect qt3, using empty QT3DIR
+"""
 
-    qt_err = """
-scons: warning: Could not detect qt, using empty QTDIR
+qt_moved = r"""
+scons: \*\*\* Deprecated tool 'qt' renamed to 'qt3'. Please update your build accordingly. 'qt3' will be removed entirely in a future release.
 """
 
-qt_warnings = [ re.compile(qt_err + TestSCons.file_expr) ]
+qt3_warnings = [re.compile(qt3_err + TestSCons.file_expr)]
+qt_error = [re.compile(qt_moved + TestSCons.file_expr)]
 
 error_output = {
-    'icl' : intel_warnings,
-    'intelc' : intel_warnings,
-    'qt' : qt_warnings,
+    'icl': intel_warnings,
+    'intelc': intel_warnings,
+    'qt3': qt3_warnings,
+    'qt': qt_error,
 }
 
 # An SConstruct for importing Tool names that have illegal characters
@@ -178,16 +181,16 @@
         test.write('SConstruct', indirect_import % locals())
     else:
         test.write('SConstruct', direct_import % locals())
-    test.run(stderr=None)
+    test.run(stderr=None, status=None)
     stderr = test.stderr()
-    if stderr:
+    if stderr or test.status:
         matched = None
         for expression in error_output.get(tool, []):
             if expression.match(stderr):
                 matched = 1
                 break
         if not matched:
-            print("Failed importing '%s', stderr:" % tool)
+            print(f"Failed importing '{tool}', stderr:")
             print(stderr)
             failures.append(tool)
 
diff --git a/testing/framework/TestSCons.py b/testing/framework/TestSCons.py
index 469f6c1c53..224a8cf9d2 100644
--- a/testing/framework/TestSCons.py
+++ b/testing/framework/TestSCons.py
@@ -1172,17 +1172,20 @@ def Qt_dummy_installation(self, dir='qt'):
         self.QT_UIC = f"{_python_} {self.workpath(dir, 'bin', 'myuic.py')}"
         self.QT_LIB_DIR = self.workpath(dir, 'lib')
 
-    def Qt_create_SConstruct(self, place):
+    def Qt_create_SConstruct(self, place, qt_tool='qt3'):
         if isinstance(place, list):
             place = test.workpath(*place)
-        self.write(place, """\
+
+        var_prefix=qt_tool.upper()
+        self.write(place, f"""\
 if ARGUMENTS.get('noqtdir', 0):
-    QTDIR = None
+    {var_prefix}DIR = None
 else:
-    QTDIR = r'%s'
+    {var_prefix}DIR = r'{self.QT}'
 DefaultEnvironment(tools=[])  # test speedup
 env = Environment(
-    QTDIR=QTDIR, QT_LIB=r'%s', QT_MOC=r'%s', QT_UIC=r'%s', tools=['default', 'qt']
+    {var_prefix}DIR={var_prefix}DIR, {var_prefix}_LIB=r'{self.QT_LIB}', {var_prefix}_MOC=r'{self.QT_MOC}',
+    {var_prefix}_UIC=r'{self.QT_UIC}', tools=['default', '{qt_tool}']
 )
 dup = 1
 if ARGUMENTS.get('variant_dir', 0):
@@ -1203,7 +1206,7 @@ def Qt_create_SConstruct(self, place):
     sconscript = File('SConscript')
 Export("env dup")
 SConscript(sconscript)
-""" % (self.QT, self.QT_LIB, self.QT_MOC, self.QT_UIC))
+""")
 
     NCR = 0  # non-cached rebuild
     CR = 1  # cached rebuild (up to date)