#
#  W A R N I N G
#  -------------
#
# This file is not part of the Qt API.  It exists purely as an
# implementation detail.  It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#

QT_CONFIGURE_REPORT =
QT_CONFIGURE_NOTES =
QT_CONFIGURE_WARNINGS =
QT_CONFIGURE_ERRORS =

defineTest(qtConfAddReport) {
    QT_CONFIGURE_REPORT += "$$join(1, $$escape_expand(\\n))"
    export(QT_CONFIGURE_REPORT)
}

defineTest(qtConfAddNote) {
    QT_CONFIGURE_NOTES += "Note: $$join(1, $$escape_expand(\\n))"
    export(QT_CONFIGURE_NOTES)
}

defineTest(qtConfAddWarning) {
    QT_CONFIGURE_WARNINGS += "WARNING: $$join(1, $$escape_expand(\\n))"
    export(QT_CONFIGURE_WARNINGS)
}

defineTest(qtConfAddError) {
    QT_CONFIGURE_ERRORS += "ERROR: $$join(1, $$escape_expand(\\n))"
    export(QT_CONFIGURE_ERRORS)
    equals(2, log):qt_conf_tests_allowed {
        CONFIG += mention_config_log
        export(CONFIG)
    }
}

defineTest(qtConfFatalError) {
    qtConfAddError($$1, $$2)
    qtConfPrintReport()
    error()
}

# Return a string list for the specified JSON path, which may be either a
# single string or an array of strings.
# Note that this returns a variable name, so it can be directly iterated over.
defineReplace(qtConfScalarOrList) {
    defined($$1, var): return($$1)
    vals = $$list()
    for (i, $${1}._KEYS_): \
        $$vals += $$eval($${1}.$$i)
    export($$vals)
    return($$vals)
}

defineTest(qtConfCommandlineSetInput) {
    arg = $${1}
    val = $${2}
    !isEmpty($${currentConfig}.commandline.options.$${arg}.name): \
        arg = $$eval($${currentConfig}.commandline.options.$${arg}.name)
    !isEmpty(config.input.$$arg) {
        oldval = $$eval(config.input.$$arg)
        equals(oldval, $$val): \
            qtConfAddNote("Option '$$arg' with value '$$val' was specified twice")
        else: \
            qtConfAddNote("Overriding option '$$arg' with '$$val' (was: '$$oldval')")
    }

    config.input.$$arg = $$val
    export(config.input.$$arg)
}

defineReplace(qtConfGetNextCommandlineArg) {
    c = $$take_first(QMAKE_EXTRA_ARGS)
    export(QMAKE_EXTRA_ARGS)
    return($$c)
}

defineReplace(qtConfPeekNextCommandlineArg) {
    return($$first(QMAKE_EXTRA_ARGS))
}

defineTest(qtConfCommandline_boolean) {
    opt = $${1}
    val = $${2}
    isEmpty(val): val = yes

    !equals(val, yes):!equals(val, no) {
        qtConfAddError("Invalid value given for boolean command line option '$$opt'.")
        return()
    }

    qtConfCommandlineSetInput($$opt, $$val)
}

defineTest(qtConfCommandline_void) {
    opt = $${1}
    val = $${2}
    !isEmpty(val) {
        qtConfAddError("Command line option '$$opt' expects no argument ('$$val' given).")
        return()
    }

    val = $$eval($${currentConfig}.commandline.options.$${opt}.value)
    isEmpty(val): val = yes

    qtConfCommandlineSetInput($$opt, $$val)
}

defineTest(qtConfCommandline_enum) {
    opt = $${1}
    val = $${2}
    isEmpty(val): val = yes

    # validate and map value
    mapped = $$eval($${currentConfig}.commandline.options.$${opt}.values.$${val})
    isEmpty(mapped) {
        # just a list of allowed values
        for (i, $${currentConfig}.commandline.options.$${opt}.values._KEYS_) {
            equals($${currentConfig}.commandline.options.$${opt}.values.$${i}, $$val) {
                mapped = $$val
                break()
            }
        }
    }
    isEmpty(mapped) {
        qtConfAddError("Invalid value '$$val' supplied to command line option '$$opt'.")
        return()
    }

    qtConfCommandlineSetInput($$opt, $$mapped)
}

defineTest(qtConfValidateValue) {
    opt = $${1}
    val = $${2}

    validValues = $$eval($${currentConfig}.commandline.options.$${opt}.values._KEYS_)
    isEmpty(validValues): \
        return(true)

    for (i, validValues) {
        equals($${currentConfig}.commandline.options.$${opt}.values.$${i}, $$val): \
            return(true)
    }

    qtConfAddError("Invalid value '$$val' supplied to command line option '$$opt'.")
    return(false)
}

defineTest(qtConfCommandline_string) {
    opt = $${1}
    val = $${2}
    nextok = $${3}
    isEmpty(val):$$nextok: val = $$qtConfGetNextCommandlineArg()

    # Note: Arguments which are variable assignments are legit here.
    contains(val, "^-.*")|isEmpty(val) {
        qtConfAddError("No value supplied to command line option '$$opt'.")
        return()
    }

    !qtConfValidateValue($$opt, $$val): \
        return()

    qtConfCommandlineSetInput($$opt, $$val)
}

defineTest(qtConfCommandline_optionalString) {
    opt = $${1}
    val = $${2}
    nextok = $${3}
    isEmpty(val) {
        $$nextok: val = $$qtConfPeekNextCommandlineArg()
        contains(val, "^-.*|[A-Z0-9_]+=.*")|isEmpty(val): \
            val = "yes"
        else: \
            val = $$qtConfGetNextCommandlineArg()
    }

    !qtConfValidateValue($$opt, $$val): \
        return()

    qtConfCommandlineSetInput($$opt, $$val)
}


defineTest(qtConfCommandline_addString) {
    opt = $${1}
    val = $${2}
    nextok = $${3}
    isEmpty(val):$$nextok: val = $$qtConfGetNextCommandlineArg()

    # Note: Arguments which are variable assignments are legit here.
    contains(val, "^-.*")|isEmpty(val) {
        qtConfAddError("No value supplied to command line option '$$opt'.")
        return()
    }

    !qtConfValidateValue($$opt, $$val): \
        return()

    !isEmpty($${currentConfig}.commandline.options.$${opt}.name): \
        opt = $$eval($${currentConfig}.commandline.options.$${opt}.name)

    config.input.$$opt += $$val
    export(config.input.$$opt)
}

defineTest(qtConfCommandline_redo) {
    !exists($$OUT_PWD/config.opt) {
        qtConfAddError("No config.opt present - cannot redo configuration.")
        return()
    }
    QMAKE_EXTRA_REDO_ARGS = $$cat($$OUT_PWD/config.opt, lines)
    export(QMAKE_EXTRA_REDO_ARGS)  # just for config.log
    QMAKE_EXTRA_ARGS = $$QMAKE_EXTRA_REDO_ARGS $$QMAKE_EXTRA_ARGS
    export(QMAKE_EXTRA_ARGS)
    QMAKE_REDO_CONFIG = true
    export(QMAKE_REDO_CONFIG)
}

defineTest(qtConfParseCommandLine) {
    customCalls =
    for (cc, allConfigs) {
        custom = $$eval($${cc}.commandline.custom)

        !isEmpty(custom) {
            customCall = qtConfCommandline_$$custom
            !defined($$customCall, test): \
                error("Custom command line callback '$$custom' is undefined.")
            customCalls += $$customCall
        }
    }

    for (ever) {
        c = $$qtConfGetNextCommandlineArg()
        isEmpty(c): break()

        didCustomCall = false
        for (customCall, customCalls) {
            $${customCall}($$c) {
                didCustomCall = true
                break()
            }
        }
        $$didCustomCall: \
            next()

        contains(c, "([A-Z0-9_]+)=(.*)") {
            opt = $$replace(c, "^([A-Z0-9_]+)=(.*)", "\\1")
            val = $$replace(c, "^([A-Z0-9_]+)=(.*)", "\\2")
            for (cc, allConfigs) {
                var = $$eval($${cc}.commandline.assignments.$${opt})
                !isEmpty(var): \
                    break()
            }
            isEmpty(var) {
                qtConfAddError("Assigning unknown variable '$$opt' on command line.")
                return()
            }
            config.input.$$var = $$val
            export(config.input.$$var)
            next()
        }

        # parse out opt and val
        nextok = false
        contains(c, "^--?enable-(.*)") {
            opt = $$replace(c, "^--?enable-(.*)", "\\1")
            val = yes
        } else: contains(c, "^--?(disable|no)-(.*)") {
            opt = $$replace(c, "^--?(disable|no)-(.*)", "\\2")
            val = no
        } else: contains(c, "^--([^=]+)=(.*)") {
            opt = $$replace(c, "^--([^=]+)=(.*)", "\\1")
            val = $$replace(c, "^--([^=]+)=(.*)", "\\2")
        } else: contains(c, "^--(.*)") {
            opt = $$replace(c, "^--(.*)", "\\1")
            val =
        } else: contains(c, "^-(.*)") {
            opt = $$replace(c, "^-(.*)", "\\1")
            val =
            nextok = true
            for (cc, allConfigs) {
                type = $$eval($${cc}.commandline.options.$${opt})
                !isEmpty(type): break()
                type = $$eval($${cc}.commandline.options.$${opt}.type)
                !isEmpty(type): break()
            }
            isEmpty(type):contains(opt, "(qt|system)-.*") {
                val = $$replace(opt, "(qt|system)-(.*)", "\\1")
                opt = $$replace(opt, "(qt|system)-(.*)", "\\2")
            }
        } else {
            qtConfAddError("Invalid command line parameter '$$c'.")
            return()
        }

        for (cc, allConfigs) {
            type = $$eval($${cc}.commandline.options.$${opt})
            isEmpty(type): \
                type = $$eval($${cc}.commandline.options.$${opt}.type)
            isEmpty(type) {
                # no match in the regular options, try matching the prefixes
                for (p, $${cc}.commandline.prefix._KEYS_) {
                    e = "^-$${p}(.*)"
                    contains(c, $$e) {
                        opt = $$eval($${cc}.commandline.prefix.$${p})
                        val = $$replace(c, $$e, "\\1")
                        nextok = true
                        type = "addString"
                        break()
                    }
                }
            }
            !isEmpty(type) {
                currentConfig = $$cc
                break()
            }
        }
        # handle builtin [-no]-feature-xxx
        isEmpty(type):contains(opt, "feature-(.*)") {
            opt ~= s,^feature-,,
            found = false
            for (cc, allConfigs) {
                contains($${cc}.features._KEYS_, $$opt) {
                    found = true
                    break()
                }
            }
            !$$found {
                qtConfAddError("Enabling/Disabling unknown feature '$$opt'.")
                return()
            }
            # this is a boolean enabling/disabling the corresponding feature
            type = boolean
        }

        isEmpty(type):contains(opt, "skip") {
            isEmpty(skipOptionWarningAdded) {
                qtConfAddWarning("Command line option -skip is only effective in top-level builds.")
                skipOptionWarningAdded = 1
            }
            val = $$qtConfGetNextCommandlineArg()
            next()
        }

        isEmpty(type) {
            qtConfAddError("Unknown command line option '$$c'.")
            equals(config.input.continue, yes): \
                next()
            else: \
                return()
        }

        call = "qtConfCommandline_$${type}"
        !defined($$call, test): \
            error("Command line option '$$c' has unknown type '$$type'.")

        # now that we have opt and value, process it
        $${call}($$opt, $$val, $$nextok)
    }
}

defineReplace(qtConfToolchainSupportsFlag) {
    test_out_dir = $$OUT_PWD/$$basename(QMAKE_CONFIG_TESTS_DIR)
    test_cmd_base = "$$QMAKE_CD $$system_quote($$system_path($$test_out_dir)) &&"

    conftest = "int main() { return 0; }"
    write_file("$$test_out_dir/conftest.cpp", conftest)|error()

    qtRunLoggedCommand("$$test_cmd_base $$QMAKE_CXX $$QMAKE_CXXFLAGS $${1} -o conftest-out conftest.cpp"): \
        return(true)
    return(false)
}

defineTest(qtConfTest_compilerSupportsFlag) {
    flag = $$eval($${1}.flag)

    return($$qtConfToolchainSupportsFlag($$flag))
}

defineTest(qtConfTest_linkerSupportsFlag) {
    flag = $$eval($${1}.flag)

    use_bfd_linker: \
        LFLAGS = -fuse-ld=bfd
    use_gold_linker: \
        LFLAGS = -fuse-ld=gold
    use_lld_linker: \
        LFLAGS = -fuse-ld=lld

    return($$qtConfToolchainSupportsFlag($$LFLAGS "-Wl,$$flag"))
}

defineReplace(qtConfFindInPathList) {
    # This nesting is consistent with Apple ld -search_paths_first,
    # and presumably with GNU ld (no actual documentation found).
    for (dir, 2) {
        for (file, 1) {
            exists("$$dir/$$file"): \
                return("$$dir/$$file")
        }
    }
    return()
}

defineReplace(qtConfFindInPath) {
    ensurePathEnv()
    equals(QMAKE_HOST.os, Windows):!contains(1, .*\\.exe): 1 = $${1}.exe
    return($$qtConfFindInPathList($$1, $$2 $$QMAKE_PATH_ENV))
}

defineReplace(qtConfPkgConfigEnv) {
    env =
    !isEmpty(PKG_CONFIG_SYSROOT_DIR): env = "$${SETENV_PFX}PKG_CONFIG_SYSROOT_DIR=$${PKG_CONFIG_SYSROOT_DIR}$${SETENV_SFX} "
    !isEmpty(PKG_CONFIG_LIBDIR): env = "$$env$${SETENV_PFX}PKG_CONFIG_LIBDIR=$${PKG_CONFIG_LIBDIR}$${SETENV_SFX} "
    return($$env)
}

defineReplace(qtConfPkgConfig) {
    host = $$1
    isEmpty(host): host = false

    $$host {
        pkg_config = $$qtConfFindInPath("pkg-config")
    } else {
        pkg_config = "$$qtConfPkgConfigEnv()$$PKG_CONFIG_EXECUTABLE"
    }

    return($$pkg_config)
}

defineTest(qtConfPkgConfigPackageExists) {
    isEmpty(1)|isEmpty(2): \
        return(false)

    !qtRunLoggedCommand("$${1} --exists --silence-errors $${2}"): \
        return(false)

    return(true)
}

defineReplace(qtSystemQuote) {
    args =
    for (a, 1): \
        args += $$system_quote($$a)
    return($$args)
}

defineReplace(qtConfPrepareArgs) {
    return($$qtSystemQuote($$split(1)))
}

defineTest(qtConfSetupLibraries) {
    asspfx = $${currentConfig}.commandline.assignments
    for (l, $${currentConfig}.libraries._KEYS_) {
        lpfx = $${currentConfig}.libraries.$${l}
        # 'export' may be omitted, in which case it falls back to the library's name
        !defined($${lpfx}.export, var) {
            $${lpfx}.export = $$replace(l, -, _)
            export($${lpfx}.export)
        }
        # 'export' may also be empty, but we need a derived identifier
        alias = $$eval($${lpfx}.export)
        isEmpty(alias): alias = $$replace(l, -, _)
        $${lpfx}.alias = $$alias
        export($${lpfx}.alias)
        # make it easy to refer to the library by its export name.
        $${currentConfig}.exports._KEYS_ += $$alias
        $${currentConfig}.exports.$$alias += $$l
        export($${currentConfig}.exports.$$alias)
        isEmpty($${lpfx}.sources._KEYS_): \
            error("Library $$l defines no sources")
        for (s, $${lpfx}.sources._KEYS_) {
            spfx = $${lpfx}.sources.$${s}
            # link back to parent object
            $${spfx}.library = $$l
            export($${spfx}.library)
            # a plain string is transformed into a structure
            isEmpty($${spfx}._KEYS_) {
                $${spfx}.libs = $$eval($${spfx})
                export($${spfx}.libs)
            }
            # if the type is missing (implicitly in the case of plain strings), assume 'inline'
            isEmpty($${spfx}.type) {
                $${spfx}.type = inline
                export($${spfx}.type)
            }
        }
    }
    $${currentConfig}.exports._KEYS_ = $$unique($${currentConfig}.exports._KEYS_)
    export($${currentConfig}.exports._KEYS_)

    for (alias, $${currentConfig}.exports._KEYS_) {
        ua = $$upper($$alias)
        $${asspfx}._KEYS_ += \
            $${ua}_PREFIX $${ua}_INCDIR $${ua}_LIBDIR \
            $${ua}_LIBS $${ua}_LIBS_DEBUG $${ua}_LIBS_RELEASE
        uapfx = $${asspfx}.$${ua}
        $${uapfx}_PREFIX = $${alias}.prefix
        $${uapfx}_INCDIR = $${alias}.incdir
        $${uapfx}_LIBDIR = $${alias}.libdir
        $${uapfx}_LIBS = $${alias}.libs
        $${uapfx}_LIBS_DEBUG = $${alias}.libs.debug
        $${uapfx}_LIBS_RELEASE = $${alias}.libs.release
        export($${uapfx}_PREFIX)
        export($${uapfx}_INCDIR)
        export($${uapfx}_LIBDIR)
        export($${uapfx}_LIBS)
        export($${uapfx}_LIBS_DEBUG)
        export($${uapfx}_LIBS_RELEASE)
    }
    export($${asspfx}._KEYS_)

    # reverse mapping for assignments on command line.
    for (a, $${asspfx}._KEYS_) {
        apfx = $${asspfx}.$${a}
        ra = config.commandline.rev_assignments.$$eval($$apfx)
        $$ra = $$a
        export($$ra)
    }
}

defineReplace(qtGccSysrootifiedPath) {
    return($$replace(1, ^=, $$[QT_SYSROOT]))
}

defineReplace(qtGccSysrootifiedPaths) {
    sysrootified =
    for (path, 1): \
        sysrootified += $$qtGccSysrootifiedPath($$path)
    return($$sysrootified)
}

# libs-var, libs, in-paths
defineTest(qtConfResolveLibs) {
    for (path, 3): \
        pre_lflags += -L$$path
    $$1 = $$pre_lflags $$2
    export($$1)
    return(true)
}

# libs-var, in-paths, libs
defineTest(qtConfResolvePathLibs) {
    ret = true
    gcc: \
        local_paths = $$qtGccSysrootifiedPaths($$2)
    else: \
        local_paths = $$2
    for (libdir, local_paths) {
        !exists($$libdir/.) {
            qtLog("Library path $$val_escape(libdir) is invalid.")
            ret = false
        }
    }
    !qtConfResolveLibs($$1, $$3, $$2): \
        ret = false
    return($$ret)
}

defineReplace(qtConfGetTestSourceList) {
    result =
    !isEmpty($${1}.test.inherit) {
        base = $$section(1, ., 0, -2)
        for (i, $${1}.test.inherit): \
            result += $$qtConfGetTestSourceList($${base}.$$i)
    }
    return($$result $$1)
}

defineReplace(qtConfGetTestIncludes) {
    defined($${1}._KEYS_, var) {
        1st = $$first($${1}._KEYS_)
        equals(1st, 0) {
            # array; recurse for every element
            ret =
            for (k, $${1}._KEYS_): \
                ret += $$qtConfGetTestIncludes($${1}.$$k)
            return($$ret)
        }
        # object; try condition and recurse
        !defined($${1}.headers, var):!defined($${1}.headers._KEYS_, var): \  # just plain broken without it
            error("headers object '$$1' has no nested headers entry")
        cond = $$eval($${1}.condition)
        isEmpty(cond): \  # would be pointless otherwise
            error("headers object '$$1' has no condition")
        !$$qtConfEvaluate($$cond) {
            qtLog("header entry '$$1' failed condition '$$cond'.")
            return()
        }
        qtLog("header entry '$$1' passed condition.")
        return($$qtConfGetTestIncludes($${1}.headers))
    }
    return($$eval($$1))  # plain string - or nothing (can happen for top-level call only)
}

# includes-var, in-paths, test-object-var
defineTest(qtConfResolvePathIncs) {
    ret = true
    gcc: \
        local_paths = $$qtGccSysrootifiedPaths($$2)
    else: \
        local_paths = $$2
    for (incdir, local_paths) {
        !exists($$incdir/.) {
            qtLog("Include path $$val_escape(incdir) is invalid.")
            ret = false
        }
    }
    2 -= $$QMAKE_DEFAULT_INCDIRS
    $$1 = $$2
    export($$1)
    wasm {
        # FIXME: emcc downloads pre-built libraries and adds their include
        # path to the clang call dynamically. it would be possible to parse
        # the emcc -s USE_xyz=1 --cflags output to populate xzy_INCDIR and
        # thus make the code below work.
        return($$ret)
    }
    tests = $$qtConfGetTestSourceList($$3)
    hdrs =
    for (test, tests): \
        hdrs += $$qtConfGetTestIncludes($${test}.headers)
    for (hdr, hdrs) {
        h = $$qtConfFindInPathList($$hdr, $$2 $$EXTRA_INCLUDEPATH $$QMAKE_DEFAULT_INCDIRS)
        isEmpty(h) {
            qtLog("$$hdr not found in [$$val_escape(2)] and global paths.")
            ret = false
        }
    }
    return($$ret)
}

# the library is specified inline in a 'libs' field.
# overrides from the command line are accepted.
defineTest(qtConfLibrary_inline) {
    lib = $$eval($${1}.library)
    !defined($${1}.libs, var):isEmpty($${1}.builds._KEYS_): \
        error("'inline' source in library '$$lib' specifies neither 'libs' nor 'builds'.")

    # library lists are specified as strings in the json sources for
    # readability, but it's a pain to work with that, so expand it now.
    eval($${1}.libs = $$eval($${1}.libs))
    export($${1}.libs)
    for (b, $${1}.builds._KEYS_) {
        eval($${1}.builds.$${b} = $$eval($${1}.builds.$${b}))
        export($${1}.builds.$${b})
    }

    # if multiple libraries provide the same export, it makes sense
    # to make them recognize the same input variables.
    input = $$eval($${2}.alias)

    # build-specific direct libs. overwrites inline libs.
    vars =
    any = false
    all = true
    for (b, $$list(debug release)) {
        iv = $${input}.libs.$${b}
        vars += $$eval(config.commandline.rev_assignments.$${iv})
        defined(config.input.$${iv}, var) {
            eval($${1}.builds.$${b} = $$eval(config.input.$${iv}))
            export($${1}.builds.$${b})
            $${1}.builds._KEYS_ *= $${b}
            any = true
        } else {
            all = false
        }
    }
    $$any {
        !$$all {
            qtConfAddError("Either none or all of $$join(vars, ", ", [, ]) must be specified.")
            return(false)
        }
        export($${1}.builds._KEYS_)
        # we also reset the generic libs, to avoid surprises.
        $${1}.libs =
        export($${1}.libs)
    }

    # direct libs. overwrites inline libs.
    defined(config.input.$${input}.libs, var) {
        eval($${1}.libs = $$eval(config.input.$${input}.libs))
        export($${1}.libs)
    }

    includes = $$eval(config.input.$${input}.incdir)

    # prefix. prepends to (possibly overwritten) inline libs.
    prefix = $$eval(config.input.$${input}.prefix)
    !isEmpty(prefix) {
        includes += $$prefix/include
        $${1}.libs = -L$$prefix/lib $$eval($${1}.libs)
        export($${1}.libs)
    }

    libdir = $$eval(config.input.$${input}.libdir)
    !isEmpty(libdir) {
        libs =
        for (ld, libdir): \
            libs += -L$$ld
        $${1}.libs = $$libs $$eval($${1}.libs)
        export($${1}.libs)
    }

    !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \
        return(false)

    return(true)
}

# the library is provided by the qmake spec.
# this source type cannot fail.
defineTest(qtConfLibrary_makeSpec) {
    spec = $$eval($${1}.spec)
    isEmpty(spec): \
        error("makeSpec source in library '$$eval($${1}.library)' does not specify 'spec'.")

    !qtConfResolvePathLibs($${1}.libs, $$eval(QMAKE_LIBDIR_$$spec), $$eval(QMAKE_LIBS_$$spec)): \
        return(false)

    !qtConfResolvePathIncs($${1}.includedir, $$eval(QMAKE_INCDIR_$$spec), $$2): \
        return(false)

    !isEmpty(QMAKE_EXPORT_INCDIR_$$spec) {
        $${1}.exportincludedir = $$eval(QMAKE_EXPORT_INCDIR_$$spec)
        export($${1}.exportincludedir)
    }

    # note that the object is re-exported, because we resolve the libraries.

    return(true)
}

# the library is found via pkg-config.
defineTest(qtConfLibrary_pkgConfig) {
    pkg_config = $$qtConfPkgConfig($$eval($${1}.host))
    isEmpty(pkg_config) {
        qtLog("pkg-config use disabled globally.")
        return(false)
    }
    args = $$qtConfPrepareArgs($$eval($${1}.args))

    !qtConfPkgConfigPackageExists($$pkg_config, $$args) {
        qtLog("pkg-config did not find package.")
        return(false)
    }

    qtRunLoggedCommand("$$pkg_config --modversion $$args", version)|return(false)
    version ~= s/[^0-9.].*$//
    $${1}.version = $$first(version)
    export($${1}.version)

    qtRunLoggedCommand("$$pkg_config --libs-only-L $$args", libpaths)|return(false)
    qtRunLoggedCommand("$$pkg_config --libs-only-l $$args", libs)|return(false)
    eval(libs = $$libpaths $$libs)
    !qtConfResolveLibs($${1}.libs, $$libs): \
        return(false)
    contains($${1}.libs, ".*\\.$${QMAKE_EXTENSION_STATICLIB}$") {
        qtRunLoggedCommand("$$pkg_config --static --libs $$args", libs)|return(false)
        # Split by space
        eval(libs = $$libs)
        !qtConfResolveLibs($${1}.libs, $$libs): \
            return(false)
    }

    qtRunLoggedCommand("$$pkg_config --cflags $$args", $${1}.cflags)|return(false)
    # Split CFLAGS into stuff that goes into DEFINES, INCLUDEPATH, and other stuff.
    # The compound variable is still set in case something wants to use it outside
    # regular library exports.
    defines =
    includes =
    ignored =
    eval(cflags = $$eval($${1}.cflags))
    for (i, cflags) {
        contains(i, "-I.*") {
            i ~= s/^-I//
            includes += $$i
        } else: contains(i, "-D.*") {
            i ~= s/^-D//
            defines += $$i
        } else {
            # Sometimes, pkg-config files include other flags
            # we really don't need and shouldn't add.
            ignored += $$i
        }
    }
    !isEmpty(ignored): \
        qtLog("Note: Dropped compiler flags '$$ignored'.")
    !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \
        return(false)
    $${1}.defines = $$defines

    # now remove the content of the transitive deps we know about.
    largs = $$qtConfAllLibraryArgs($$eval($${2}.dependencies))
    for (la, largs): \
        eval("$$la")
    USES = $$eval($$list($$upper($$replace(QMAKE_USE, -, _))))
    # _CC == _LD for configure's library sources, so pick first arbitrarily.
    DEPS = $$resolve_depends(USES, QMAKE_DEPENDS_, _CC)
    for (DEP, DEPS) {
        $${1}.libs -= $$eval(QMAKE_LIBS_$${DEP})
        $${1}.includedir -= $$eval(QMAKE_INCDIR_$${DEP})
        $${1}.defines -= $$eval(QMAKE_DEFINES_$${DEP})
    }
    export($${1}.libs)
    export($${1}.includedir)
    export($${1}.defines)

    return(true)
}

defineTest(qtConfTest_getPkgConfigVariable) {
    pkg_config = $$qtConfPkgConfig($$eval($${1}.host))
    isEmpty(pkg_config): \
        return(false)
    args = $$qtConfPrepareArgs($$eval($${1}.pkg-config-args))

    !qtConfPkgConfigPackageExists($$pkg_config, $$args): \
        return(false)

    variable = $$eval($${1}.pkg-config-variable)
    qtRunLoggedCommand("$$pkg_config --variable=$$variable $$args", $${1}.value)|return(false)
    export($${1}.value)
    $${1}.cache += value
    export($${1}.cache)
    return(true)
}

defineReplace(qtConfLibraryArgs) {
    NAME = $$upper($$replace($${1}.library, -, _))
    qmake_args = "QMAKE_LIBS_$${NAME} = $$val_escape($${1}.libs)"
    for (b, $${1}.builds._KEYS_): \
        qmake_args += "QMAKE_LIBS_$${NAME}_$$upper($$b) = $$val_escape($${1}.builds.$${b})"
    includedir = $$eval($${1}.includedir)
    !isEmpty(includedir): \
        qmake_args += "QMAKE_INCDIR_$${NAME} = $$val_escape(includedir)"
    defines = $$eval($${1}.defines)
    !isEmpty(defines): \
        qmake_args += "QMAKE_DEFINES_$${NAME} = $$val_escape(defines)"
    depends = $$eval($${2}.dependencies)
    !isEmpty(depends) {
        dep_uses =
        for (use, depends): \
            dep_uses += $$section(use, :, 1, 1)
        qmake_args += \
            "QMAKE_DEPENDS_$${NAME}_CC = $$upper($$replace(dep_uses, -, _))" \
            "QMAKE_DEPENDS_$${NAME}_LD = $$upper($$replace(dep_uses, -, _))"
    }
    return($$qmake_args)
}

defineReplace(qtConfAllLibraryArgs) {
    isEmpty(1): return()
    dep_uses =
    for (use, 1): \
        dep_uses += $$section(use, :, 1, 1)
    dep_args =
    seen =
    for(ever) {
        isEmpty(1): break()
        use = $$take_last(1)
        contains(seen, $$use): next()
        seen += $$use
        use_cfg = $$section(use, :, 0, 0)
        !isEmpty(use_cfg) {
            use_lib = $$section(use, :, 1, 1)
            lpfx = $${use_cfg}.libraries.$$use_lib
            dep_args += $$qtConfLibraryArgs($${lpfx}.sources.$$eval($${lpfx}.source), $$lpfx)
            1 += $$eval($${lpfx}.dependencies)
        }
    }
    return("QMAKE_USE += $$dep_uses" $$dep_args)
}

defineTest(qtConfExportLibrary) {
    lpfx = $${currentConfig}.libraries.$$1
    alias = $$eval($${lpfx}.alias)
    $${currentConfig}.found.$$alias = $$1
    export($${currentConfig}.found.$$alias)
    name = $$eval($${lpfx}.export)
    isEmpty(name): return()
    spfx = $${lpfx}.sources.$$eval($${lpfx}.source)
    !$$qtConfEvaluate($$eval($${spfx}.export)): return()

    output = privatePro
    NAME = $$upper($$name)
    # LIBS is emitted even if empty, as this allows the library to be "seen".
    libs = $$eval($${spfx}.libs)
    qtConfOutputVar(assign, $$output, QMAKE_LIBS_$$NAME, $$libs)
    for (b, $${spfx}.builds._KEYS_) {
        blibs = $$eval($${spfx}.builds.$${b})
        qtConfOutputVar(assign, $$output, QMAKE_LIBS_$${NAME}_$$upper($$b), $$blibs)
    }
    defines = $$eval($${spfx}.defines)
    !isEmpty(defines): qtConfOutputVar(assign, $$output, QMAKE_DEFINES_$$NAME, $$defines)
    includes = $$eval($${spfx}.exportincludedir)
    !equals(includes, -) {
        isEmpty(includes): includes = $$eval($${spfx}.includedir)
        !isEmpty(includes): qtConfOutputVar(assign, $$output, QMAKE_INCDIR_$$NAME, $$includes)
    }
    uses = $$eval($${lpfx}.dependencies)
    !isEmpty(uses) {
        # FIXME: ideally, we would export transitive deps only for static
        # libs, to not extend the link interface unduly. however, the system
        # does currently not differentiate between public and private deps.
        depends =
        for (use, uses) {
            use_cfg = $$section(use, :, 0, 0)
            use_lib = $$section(use, :, 1, 1)
            !isEmpty(use_cfg): \
                depends += $$upper($$eval($${use_cfg}.libraries.$${use_lib}.export))
            else: \
                depends += $$upper($$replace(use_lib, -, _))
        }
        # we use suffixes instead of infixes, because $$resolve_depends() demands it.
        qtConfOutputVar(assign, $$output, QMAKE_DEPENDS_$${NAME}_CC, $$depends)
        qtConfOutputVar(assign, $$output, QMAKE_DEPENDS_$${NAME}_LD, $$depends)
    }
    !isEmpty($${currentConfig}.module): \
        qtConfExtendVar($$output, "QT.$${currentModule}_private.libraries", $$name)
}

defineTest(qtConfHandleLibrary) {
    lpfx = $${currentConfig}.libraries.$$1
    defined($${lpfx}.result, var): return()

    alias = $$eval($${lpfx}.alias)
    !isEmpty($${currentConfig}.found.$$alias) {
        # this happening indicates a logic error in the conditions
        # of the feature(s) referring to this library.
        # note that this does not look across module boundaries, as
        # multiple modules may know the same libraries; de-duplication
        # happens via the cache (obviously, this assumes identical
        # definitions and logic).
        error("A library exporting '$$alias' was already found.")
    }

    qtConfEnsureTestTypeDeps("library")
    !qtConfTestPrepare_compile($$lpfx) {
        $${lpfx}.result = false
        export($${lpfx}.result)
        return()
    }
    $${lpfx}.dependencies = $$eval($${lpfx}.resolved_uses)
    export($${lpfx}.dependencies)

    qtConfLoadResult($${lpfx}, $$1, "library") {
        $$eval($${lpfx}.result): \
            qtConfExportLibrary($$1)
        return()
    }

    qtLogTestIntro($${lpfx}, "looking for library $${1}")
    qtPersistLog()

    result = false
    for (s, $${lpfx}.sources._KEYS_) {
        spfx = $${lpfx}.sources.$${s}

        t = $$eval($${spfx}.type)
        call = qtConfLibrary_$$t
        !defined($$call, test): \
            error("Library $${1} source $${s} has unknown type '$$t'")

        qtLog("Trying source $$s (type $$t) of library $${1} ...")

        cond = $$eval($${spfx}.condition)
        !$$qtConfEvaluate($$cond) {
            qtLog("  => source failed condition '$$cond'.")
            next()
        }

        !$${call}($$spfx, $$lpfx) {
            qtLog("  => source produced no result.")
            next()
        }

        $${lpfx}.source = $$s
        export($${lpfx}.source)

        # if the library defines a test, use it to verify the source.
        defined($${lpfx}.test, var)|defined($${lpfx}.test._KEYS_, var) {
            $${lpfx}.resolved_uses = $$currentConfig:$$1
            $${lpfx}.host = $$eval($${spfx}.host)
            !qtConfTest_compile($$lpfx) {
                qtLog(" => source failed verification.")
                next()
            }
        }

        qtLog(" => source accepted.")

        $${lpfx}.cache += source
        for (v, $$list(libs includedir cflags version export)): \
            $${lpfx}.cache += sources.$${s}.$${v}
        for (b, $${spfx}.builds._KEYS_): \
            $${lpfx}.cache += sources.$${s}.builds.$${b}

        # immediately output the library as well.
        qtConfExportLibrary($$1)

        result = true
        break()
    }

    $${lpfx}.msgs = $$qtPersistedLog()
    export($${lpfx}.msgs)

    qtLogTestResult($${lpfx}, $$result)

    $${lpfx}.result = $$result
    export($${lpfx}.result)
    qtConfSaveResult($${lpfx}, $$1)
}

# This is a fake test type for the test dependency system.
defineTest(qtConfTest_library) {
    error("The test type 'library' may not be instantiated.")
}

defineTest(qtConfTestPrepare_compile) {
    !isEmpty($${1}.use._KEYS_) {
        uses =
        for (k, $${1}.use._KEYS_) {
            use = $$eval($${1}.use.$${k}.lib)
            isEmpty(use): \
                error("'use' entry $$k in test $$1 lacks 'lib' field.")
            !$$qtConfEvaluate($$eval($${1}.use.$${k}.condition)): \
                next()
            uses += $$use
        }
    } else {
        uses = $$split($${1}.use)
    }
    for (u, uses) {
        libConfig =
        exports = $$eval($${currentConfig}.exports.$$u)
        !isEmpty(exports) {
            # using a local library by exported name.
            ru = $$eval($${currentConfig}.found.$$u)
            !isEmpty(ru) {
                # if it was already found, all is good.
                u = $$ru
            } else: count(exports, 1) {
                # otherwise, if there is only one option, ensure it's resolved.
                u = $$exports
                qtConfHandleLibrary($$u)
            } else {
                # otherwise, verify that all options were resolved.
                for (x, exports) {
                    isEmpty($${currentConfig}.libraries.$${x}.result) {
                        # the higher-level logic is in the features, which we cannot
                        # infer from here. so the only option is failing.
                        error("Test $$1 refers to yet unresolved library export '$$u'")
                    }
                }
                return(false)
            }
            libConfig = $$currentConfig
        } else: contains($${currentConfig}.libraries._KEYS_, $$u) {
            # using a local library by real name. this should be the exception.
            qtConfHandleLibrary($$u)
            libConfig = $$currentConfig
        } else {
            for (d, QMAKE_LIBRARY_DEPS) {
                exports = $$eval($${d}.exports.$$u)
                !isEmpty(exports) {
                    # using a foreign library by exported name.
                    # foreign libraries may be external (if they are from a different
                    # repository and the build is modular), and using these by real
                    # name is impossible. so for consistency, uses by real name are
                    # limited to local libraries.
                    ru = $$eval($${d}.found.$$u)
                    !isEmpty(ru) {
                        u = $$ru
                        libConfig = $$d
                        break()
                    }
                    for (x, exports) {
                        isEmpty($${d}.libraries.$${x}.result): \
                            error("Test $$1 refers to unresolved library export '$$u' in '$$d'")
                    }
                    return(false)
                }
            }
        }
        isEmpty(libConfig) {
            nu = $$upper($$replace(u, -, _))
            !defined(QMAKE_LIBS_$$nu, var): \
                error("Test $$1 tries to use undeclared library '$$u'")
            # using an external library by exported name.
            $${1}.resolved_uses += :$$u
        } else {
            lpfx = $${libConfig}.libraries.$${u}
            !equals($${lpfx}.result, true): \
                return(false)
            $${1}.resolved_uses += $$libConfig:$$u
        }
    }
    export($${1}.resolved_uses)
    return(true)
}

defineTest(qtConfPrepareCompileTestSource) {
    test_dir = $$2

    tests = $$qtConfGetTestSourceList($$1)

    test_lang = "c++"
    for (test, tests): \
        test_lang += $$eval($${test}.test.lang)
    test_lang = $$last(test_lang)  # Last non-empty, that is.

    equals(test_lang, "c++"): suffix = "cpp"
    else: equals(test_lang, "c"): suffix = "c"
    else: equals(test_lang, "objc"): suffix = "m"
    else: equals(test_lang, "objc++"): suffix = "mm"
    else: error("Unknown language '$$test_lang' in compile test $$1")

    # Create source code
    contents = "/* Generated by configure */"
    # Custom code before includes
    for (test, tests): \
        for (ent, $$qtConfScalarOrList($${test}.test.head)): \
            contents += $$ent
    # Includes
    for (test, tests) {
        hdrs = $$qtConfGetTestIncludes($${test}.test.include)
        isEmpty(hdrs): \
            hdrs = $$qtConfGetTestIncludes($${test}.headers)
        for (ent, hdrs): \
            contents += "$${LITERAL_HASH}include <$$ent>"
    }
    # Custom code after includes
    for (test, tests): \
        for (ent, $$qtConfScalarOrList($${test}.test.tail)): \
            contents += $$ent
    # And finally the custom code inside main()
    contents += \
        "int main(int argc, char **argv)" \
        "{" \
        "    (void)argc; (void)argv;" \
        "    /* BEGIN TEST: */"
    for (test, tests): \
        for (ent, $$qtConfScalarOrList($${test}.test.main)): \
            contents += "    $$ent"
    contents += \
        "    /* END TEST */" \
        "    return 0;" \
        "}"
    write_file($$test_dir/main.$$suffix, contents)|error()

    for (test, tests) {
        for (file, $$qtConfScalarOrList($${test}.test.files._KEYS_)): \
            write_file($$test_dir/$$file, $$qtConfScalarOrList($${test}.test.files.$${file}))|error()
    }

    # Create stub .pro file
    contents = "SOURCES = main.$$suffix"
    # Custom project code
    pwd = $$val_escape($${currentConfig}.dir)
    for (test, tests): \
        for (ent, $$qtConfScalarOrList($${test}.test.qmake)): \
            contents += $$replace(ent, "@PWD@", $$pwd)
    write_file($$test_dir/$$basename(test_dir).pro, contents)|error()
}

defineTest(qtConfTest_compile) {
    test = $$eval($${1}.test)
    host = $$eval($${1}.host)
    isEmpty(host): host = false

    test_base_out_dir = $$OUT_PWD/$$basename(QMAKE_CONFIG_TESTS_DIR)
    isEmpty(test) {
        test_dir = $$test_base_out_dir/$$section(1, ".", -1)
        test_out_dir = $$test_dir
        qtConfPrepareCompileTestSource($$1, $$test_dir)
    } else {
        test_dir = $$QMAKE_CONFIG_TESTS_DIR/$$test
        test_out_dir = $$test_base_out_dir/$$test
        !isEmpty($${1}.pro): \
            test_dir = $$test_dir/$$eval($${1}.pro)
    }
    test_cmd_base = "$$QMAKE_CD $$system_quote($$system_path($$test_out_dir)) &&"

    qmake_args = $$qtConfPkgConfigEnv()$$system_quote($$system_path($$QMAKE_QMAKE))
    !isEmpty(QMAKE_QTCONF): \
        qmake_args += -qtconf $$system_quote($$QMAKE_QTCONF)

    # Disable qmake features which are typically counterproductive for tests
    qmake_args += "\"CONFIG -= qt debug_and_release app_bundle lib_bundle\""

    # allow tests to behave differently depending on the type of library
    # being built (shared/static). e.g. see config.tests/unix/icu
    shared: \
        qmake_configs = "shared"
    else: \
        qmake_configs = "static"

    use_bfd_linker: \
        qmake_configs += "use_bfd_linker"
    use_gold_linker: \
        qmake_configs += "use_gold_linker"
    use_lld_linker: \
        qmake_configs += "use_lld_linker"

    # disable warnings from the builds, since they're just noise at this point.
    qmake_configs += "warn_off"

    # add console to the CONFIG variable when running the tests, so that they
    # can work with a regular main() entry point on Windows.
    qmake_configs += "console"

    # for platforms with multiple architectures (macOS, iOS, tvOS, watchOS),
    # make sure tests are only built for a single architecture
    qmake_configs += "single_arch"

    qmake_args += "\"CONFIG += $$qmake_configs\""

    !$$host|!cross_compile {
        # On WinRT we need to change the entry point as we cannot create windows
        # applications
        winrt: \
            qmake_args += " \"QMAKE_LFLAGS += /ENTRY:main\""

        # add compiler flags, these are set for the target and should not be applied to host tests
        !isEmpty(EXTRA_DEFINES): \
            qmake_args += $$system_quote(DEFINES += $$val_escape(EXTRA_DEFINES))
        !isEmpty(EXTRA_LIBDIR): \
            qmake_args += $$system_quote(QMAKE_LIBDIR += $$val_escape(EXTRA_LIBDIR))
        !isEmpty(EXTRA_FRAMEWORKPATH): \
            qmake_args += $$system_quote(QMAKE_FRAMEWORKPATH += $$val_escape(EXTRA_FRAMEWORKPATH))
        !isEmpty(EXTRA_INCLUDEPATH): \
            qmake_args += $$system_quote(INCLUDEPATH += $$val_escape(EXTRA_INCLUDEPATH))
        qmake_args += $$EXTRA_QMAKE_ARGS
    }

    # make sure to make this the last override (because of -early)
    cross_compile {
        # must be done before loading default_pre.prf.
        qmake_args += -early "\"CONFIG += cross_compile\""
    }

    # Clean up after previous run
    exists($$test_out_dir/Makefile): \
        QMAKE_MAKE = "$$QMAKE_MAKE clean && $$QMAKE_MAKE"

    mkpath($$test_out_dir)|error()
    cont = "CONFIG += QTDIR_build"
    write_file($$test_base_out_dir/.qmake.cache, cont)|error()

    $${1}.literal_args += $$qtConfAllLibraryArgs($$eval($${1}.resolved_uses))

    # add possible command line args
    qmake_args += \
        $$qtConfPrepareArgs($$eval($${1}.args)) \
        $$qtSystemQuote($$eval($${1}.literal_args))

    qtRunLoggedCommand("$$test_cmd_base $$qmake_args $$system_quote($$test_dir)") {
        qtRunLoggedCommand("$$test_cmd_base $$QMAKE_MAKE"): \
            return(true)
    }

    return(false)
}

defineTest(qtConfTest_files) {
    for(i, $${1}.files._KEYS_) {
        f = $$eval($${1}.files.$${i})
        qtLog("Searching for file $${f}.")
        contains(f, ".*\\.h") {
            file = $$qtConfFindInPathList($$f, $$EXTRA_INCLUDEPATH $$QMAKE_DEFAULT_INCDIRS)
        } else: contains(f, ".*\\.(lib|so|a)") {
            file = $$qtConfFindInPathList($$f, $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS)
        } else {
            # assume we're looking for an executable
            file = $$qtConfFindInPath($$f, $$EXTRA_PATH)
        }
        isEmpty(file) {
            qtLog("    Not found.");
            return(false)
        }
        qtLog("    Found at $${file}.")
    }
    return(true)
}

defineTest(logn) {
    log("$${1}$$escape_expand(\\n)")
}

defineTest(qtLogTestIntro) {
    label = $$eval($${1}.label)
    isEmpty(label): return()

    isEmpty(3): log("Checking for $${label}... ")
    $$QMAKE_CONFIG_VERBOSE: log("$$escape_expand(\\n)")
    write_file($$QMAKE_CONFIG_LOG, 2, append)
}

defineTest(qtLogTestResult) {
    isEmpty($${1}.label): return()

    !isEmpty($${1}.log) {
        field = $$eval($${1}.log)
        log_msg = $$eval($${1}.$$field)
        msg = "test $$1 gave result $$log_msg"
    } else: $${2} {
        log_msg = yes
        msg = "test $$1 succeeded"
    } else {
        log_msg = no
        msg = "test $$1 FAILED"
    }
    $$QMAKE_CONFIG_VERBOSE: log_msg = $$msg
    isEmpty(3): logn("$$log_msg")
    write_file($$QMAKE_CONFIG_LOG, msg, append)
}

defineTest(qtConfSaveResult) {
    equals($${1}.cache, -): \
        return()
    keys = result msgs $$eval($${1}.cache)
    cont = "cache.$${2}._KEYS_ = $$keys"
    cache.$${2}._KEYS_ = $$keys
    export(cache.$${2}._KEYS_)
    for (k, keys) {
        cont += "cache.$${2}.$${k} = $$val_escape($${1}.$${k})"
        cache.$${2}.$${k} = $$eval($${1}.$${k})
        export(cache.$${2}.$${k})
    }
    write_file($$QMAKE_CONFIG_CACHE, cont, append)|error()
}

defineTest(qtConfLoadResult) {
    equals(QMAKE_CONFIG_CACHE_USE, none): \
        return(false)
    isEmpty(cache.$${2}._KEYS_): \
        return(false)
    equals(QMAKE_CONFIG_CACHE_USE, positive):!$$eval(cache.$${2}.result): \
        return(false)
    for (k, cache.$${2}._KEYS_) {
        $${1}.$${k} = $$eval(cache.$${2}.$${k})
        export($${1}.$${k})
    }
    # we could print the cached result, but that's basically just noise -
    # the explicitly generated summary is supposed to contain all relevant
    # information.
    qtLogTestIntro($$1, "loaded result for $$3 $$1", false)
    qtLog($$eval($${1}.msgs))
    qtLogTestResult($$1, $$eval($${1}.result), false)
    return(true)
}

defineTest(qtConfIsBoolean) {
    equals(1, "true")|equals(1, "false"): \
        return(true)
    return(false)
}

defineTest(qtConfSetupTestTypeDeps) {
    for (tt, $${currentConfig}.testTypeDependencies._KEYS_) {
        !defined(qtConfTest_$${tt}, test): \
            error("Declaring dependency for undefined test type '$$tt'.")
        for (f, $${currentConfig}.testTypeDependencies.$${tt}._KEYS_) {
            feature = $$eval($${currentConfig}.testTypeDependencies.$${tt}.$${f})
            isEmpty($${currentConfig}.features.$${feature}._KEYS_): \
                error("Test type '$$tt' depends on undefined feature '$$feature'.")
        }
    }
    # Test type aliasing means that one test type's callback is called by
    # another test type's callback. Put differently, one callback forwards
    # the call to another one. The former representation is more natural
    # (and concise) to write, while the latter is more efficient to process.
    # Hence, this function inverts the mapping.
    for (tt, $${currentConfig}.testTypeAliases._KEYS_) {
        !defined(qtConfTest_$${tt}, test): \
            error("Aliasing undefined test type '$$tt'.")
        for (tta, $${currentConfig}.testTypeAliases.$${tt}._KEYS_) {
            type = $$eval($${currentConfig}.testTypeAliases.$${tt}.$${tta})
            !defined(qtConfTest_$${type}, test): \
                error("Aliasing '$$tt' to undefined test type '$$type'.")
            $${currentConfig}.testTypeForwards.$${type} += $$tt
            export($${currentConfig}.testTypeForwards.$${type})
        }
    }
}

defineTest(qtConfEnsureTestTypeDepsOne) {
    depsn = $${currentConfig}.testTypeDependencies.$${1}._KEYS_
    !isEmpty($$depsn) {
        for (dep, $$depsn) {
            feature = $$eval($${currentConfig}.testTypeDependencies.$${1}.$${dep})
            !qtConfCheckFeature($$feature): \
                error("Test type '$$1' depends on non-emitted feature $${feature}.")
        }
        $$depsn =
        export($$depsn)
    }
    fwdsn = $${currentConfig}.testTypeForwards.$${1}
    !isEmpty($$fwdsn) {
        for (fwd, $$fwdsn): \
           qtConfEnsureTestTypeDepsOne($$fwd)
        $$fwdsn =
        export($$fwdsn)
    }
}

defineTest(qtConfEnsureTestTypeDeps) {
    qtConfEnsureTestTypeDepsOne($$1)
    currentConfig = config.builtins
    qtConfEnsureTestTypeDepsOne($$1)
}

defineTest(qtRunSingleTest) {
    tpfx = $${currentConfig}.tests.$${1}
    defined($${tpfx}.result, var): \
        return()

    type = $$eval($${tpfx}.type)
    call = "qtConfTest_$$type"
    !defined($$call, test): \
        error("Configure test $${1} refers to nonexistent type $$type")

    qtConfEnsureTestTypeDeps($$type)

    preCall = "qtConfTestPrepare_$$type"
    defined($$preCall, test):!$${preCall}($${tpfx}) {
        $${tpfx}.result = false
        export($${tpfx}.result)
        # don't cache the result; the pre-deps have their own caches.
        return()
    }

    # note: we do this only after resolving the dependencies and the
    # preparation (which may resolve libraries), so that caching does
    # not alter the execution order (and thus the output).
    qtConfLoadResult($${tpfx}, $$1, "config test"): \
        return()

    qtLogTestIntro($${tpfx}, "executing config test $${1}")
    qtPersistLog()

    result = false
    $${call}($${tpfx}): result = true

    $${tpfx}.msgs = $$qtPersistedLog()
    export($${tpfx}.msgs)

    qtLogTestResult($${tpfx}, $$result)

    $${tpfx}.result = $$result
    export($${tpfx}.result)
    qtConfSaveResult($${tpfx}, $$1)
}

defineTest(qtConfHaveModule) {
    module = $$replace(1, -, _)
    !isEmpty(QT.$${module}.skip):$$eval(QT.$${module}.skip): \
        return(false)
    !isEmpty(QT.$${module}.name): \
        return(true)
    return(false)
}

defineReplace(qtConfEvaluate) {
    isEmpty(1): return(true)

    1 ~= s/$$escape_expand(\\t)/ /g
    1 ~= s/$$escape_expand(\\r)//g
    1 ~= s/$$escape_expand(\\n) */ /g
    expr = $${1}
    expr ~= s/&&/ && /g
    expr ~= s/\\|\\|/ || /g
    expr ~= s/!/ ! /g
    expr ~= s/\\(/ ( /g
    expr ~= s/\\)/ ) /g
    expr ~= s/ *== */==/g
    expr ~= s/ *! = */!=/g
    expr_list = $$eval($$list($$expr))
    return($$qtConfEvaluateSubExpression($${1}, $$expr_list, 0))
}

defineReplace(qtConfEvaluateSingleExpression) {
    e = $${2}

    equals(e, true) {
        result = true
    } else: equals(e, false) {
        result = false
    } else: contains(e, "^[0-9]+$") {
        # numbers
        result = $$e
    } else: contains(e, "^'.*'$") {
        # quoted literals
        result = $$replace(e, "^'(.*)'$", "\\1")
    } else: contains(e, "^tests\\..*") {
        !qt_conf_tests_allowed: \
            error("Expression '$${1}' refers to a test, which is not allowed at this stage of configuring.")
        test = $$section(e, ".", 1, 1)
        var = $$section(e, ".", 2, -1)
        isEmpty(var): \
            var = result
        !contains($${currentConfig}.tests._KEYS_, $$test): \
            error("Unknown test object $${test} in expression '$${1}'.")
        qtRunSingleTest($$test)
        result = $$eval($${currentConfig}.tests.$${test}.$${var})
    } else: contains(e, "^libs\\..*") {
        !qt_conf_tests_allowed: \
            error("Expression '$${1}' refers to a library, which is not allowed at this stage of configuring.")
        lib = $$section(e, ".", 1, 1)
        var = $$section(e, ".", 2, -1)
        isEmpty(var): \
            var = result
        !contains($${currentConfig}.libraries._KEYS_, $$lib): \
            error("Unknown library object $${lib} in expression '$${1}'.")
        qtConfHandleLibrary($$lib)
        !defined($${currentConfig}.libraries.$${lib}.$${var}, var): \
            var = sources.$$eval($${currentConfig}.libraries.$${lib}.source).$$var
        result = $$eval($${currentConfig}.libraries.$${lib}.$${var})
    } else: contains(e, "^features\\..*") {
        feature = $$section(e, ".", 1, 1)
        var = $$section(e, ".", 2, -1)
        isEmpty(var): \
            var = available
        !contains($${currentConfig}.features._KEYS_, $$feature) {
            # this is basically a copy of what qtConfig() in qt_build_config.prf
            # does, but we produce a nicer error message.
            for (module, QMAKE_CONFIG_DEPS) {
                contains(QT.$${module}.enabled_features, $$feature): \
                    result = true
                else: contains(QT.$${module}.disabled_features, $$feature): \
                    result = false
                else: \
                    next()
                !equals(var, available): \
                    error("Expression '$$1' is accessing field '$$var' of non-local feature $${feature}.")
                return($$result)
            }
            error("Unknown feature object $${feature} in expression '$${1}'.")
        }
        !qtConfCheckFeature($$feature): \
            error("Expression '$$1' is accessing non-emitted feature $${feature}.")
        result = $$eval($${currentConfig}.features.$${feature}.$${var})
    } else: contains(e, "^config\\..*") {
        var = $$replace(e, "^config\\.", "")
        result = false
        contains(CONFIG, $$var): result = true
    } else: contains(e, "^module\\..*") {
        var = $$replace(e, "^module\\.", "")
        result = false
        qtConfHaveModule($$var): result = true
    } else: contains(e, "^arch\\..*") {
        var = $$replace(e, "^arch\\.", "")
        result = false
        isEmpty(QT_ARCH): \
            qtConfCheckFeature(architecture)
        contains(QT_ARCH, $$var): result = true
    } else: contains(e, "^subarch\\..*") {
        var = $$replace(e, "^subarch\\.", "")
        result = false
        isEmpty(QT_ARCH): \
            qtConfCheckFeature(architecture)
        contains(QT_CPU_FEATURES.$$QT_ARCH, $$var): result = true
    } else: contains(e, "^input\\..*") {
        result = $$eval(config.$$e)
    } else: contains(e, "^var\\..*") {
        var = $$replace(e, "^var\\.", "")
        result = $$eval($$var)
    } else: contains(e, "^call\\..*") {
        call = $$replace(e, "^call\\.", "qtConfFunc_")
        !defined($$call, replace): \
            error("Call $$call referenced in expression '$${1}' does not exist")
        eval(result = \$\$"$$call"())
    } else {
        error("Unrecognized token $$e in expression '$${1}'")
    }
    return($$result)
}

defineReplace(qtConfEvaluateSubExpression) {
    expr_list = $${2}
    result = true
    negate = false
    runSubExpression = false
    nesting_level = 0
    for (n, $${3}..$$num_add($$size(expr_list), -1)) {
        e = $$member(expr_list, $$n)
        $$runSubExpression {
            runSubExpression = false
            result = $$qtConfEvaluateSubExpression($${1}, $$expr_list, $$n)
        } else: isEqual(e, "(") {
            isEqual(nesting_level, 0): runSubExpression = true
            nesting_level = $$num_add($$nesting_level, 1)
            next()
        } else: isEqual(e, ")") {
            nesting_level = $$num_add($$nesting_level, -1)
            lessThan(nesting_level, 0): break()
            next()
        } else: greaterThan(nesting_level, 0) {
            next()
        } else: isEqual(e, "!") {
            negate = true
            next()
        } else: isEqual(e, "&&") {
            !qtConfIsBoolean($$result): \
                error("Left hand side of && is non-boolean value '$$result' in expression '$${1}'")
            !$$result: return(false)
        } else: isEqual(e, "||") {
            !qtConfIsBoolean($$result): \
                error("Left hand side of || is non-boolean value '$$result' in expression '$${1}'")
            $$result: return(true)
        } else {
            contains(e, ".*==.*") {
                lhs = $$qtConfEvaluateSingleExpression($${1}, $$replace(e, "==.*", ""))
                rhs = $$qtConfEvaluateSingleExpression($${1}, $$replace(e, ".*==", ""))
                result = false
                equals(lhs, $$rhs): result = true
            } else: contains(e, ".*!=.*") {
                lhs = $$qtConfEvaluateSingleExpression($${1}, $$replace(e, "!=.*", ""))
                rhs = $$qtConfEvaluateSingleExpression($${1}, $$replace(e, ".*!=", ""))
                result = false
                !equals(lhs, $$rhs): result = true
            } else {
                result = $$qtConfEvaluateSingleExpression($${1}, $$e)
            }
        }
        $$negate {
            !qtConfIsBoolean($$result): \
                error("Attempting to negate a non-boolean value '$$result' in expression '$${1}'")
            $$result: \
                result = false
            else: \
                result = true
            negate = false
        }
    }
    return($$result)
}

defineReplace(qtIsFeatureEnabled) {
    enable = $$eval($${currentConfig}.features.$${1}.enable)
    !isEmpty(enable) {
        $$qtConfEvaluate($$enable): \
            return(true)
    } else {
        equals(config.input.$${1}, "yes"): \
            return(true)
    }

    return(false)
}

defineReplace(qtIsFeatureDisabled) {
    disable = $$eval($${currentConfig}.features.$${1}.disable)
    !isEmpty(disable) {
        $$qtConfEvaluate($$disable): \
            return(true)
    } else {
        equals(config.input.$${1}, "no"): \
            return(true)
    }

    return(false)
}

defineReplace(qtConfCheckSingleCondition) {
    result = $$qtConfEvaluate($$2)

    !qtConfIsBoolean($$result): \
        error("Evaluation of condition '$$2' yielded non-boolean value '$$result' in feature '$${1}'.")

    !$$result {
        $${3} {
            qtConfAddError("Feature '$${1}' was enabled, but the pre-condition '$$2' failed.", log)
            $$result = true
        }
    }
    return($$result)
}

defineTest(qtConfCheckFeature) {
    fpfx = $${currentConfig}.features.$${1}

    available = $$eval($${fpfx}.available)
    !isEmpty(available): return(true)

    # skip features that will not get emitted anyway
    emitIf = $$qtConfEvaluate($$eval($${fpfx}.emitIf))
    enabled = $$qtIsFeatureEnabled($$1)
    disabled = $$qtIsFeatureDisabled($$1)

    !$$emitIf {
        $$enabled|$$disabled: \
            qtConfAddWarning("Feature $${1} is insignificant in this configuration, ignoring related command line option(s).")
        return(false)
    }

    $$disabled {
        result = false
    } else: !$$enabled:!$$qtConfEvaluate($$eval($${fpfx}.autoDetect)) {
        # feature not auto-detected and not explicitly enabled
        result = false
    } else {
        result = true
        for (condition, $$qtConfScalarOrList($${fpfx}.condition)) {
            result = $$qtConfCheckSingleCondition($$1, $$condition, $$enabled)
            !$$result: break()
        }
    }
    $${fpfx}.available = $$result
    export($${fpfx}.available)

    for (i, $${fpfx}.output._KEYS_): \
        qtConfProcessOneOutput($${1}, $$i)

    return(true)
}

defineTest(qtConfCheckModuleCondition) {
    QT.$${currentModule}.skip = false
    !$$qtConfEvaluate($$eval($${currentConfig}.condition)): \
        QT.$${currentModule}.skip = true
    export(QT.$${currentModule}.skip)

    # ensure qtConfHaveModule() works
    QT.$${currentModule}.name = -
    export(QT.$${currentModule}.name)
}


defineTest(qtConfProcessFeatures) {
    for (feature, $${currentConfig}.features._KEYS_): \
        qtConfCheckFeature($$feature)
}

#
# reporting
#

defineReplace(qtConfPadCols) {
    pad = $$num_add($$str_size($$2), -$$str_size($${1}))
    lessThan(pad, 0): pad = 0
    return("$$1 $$str_member($$2, 0, $$pad) $$3")
}

defineTest(qtConfReportPadded) {
    qtConfAddReport($$qtConfPadCols($$1, "........................................", $$2))
}

defineReplace(qtConfCollectFeatures) {
    l =
    for (feature, $$list($${1})) {
        $$eval($${currentConfig}.features.$${feature}.available): \
            l += $$eval($${currentConfig}.features.$${feature}.label)
    }

    isEmpty(l): return("<none>")
    return($$join(l, ' '))
}

defineTest(qtConfReport_featureList) {
    qtConfReportPadded($${1}, $$qtConfCollectFeatures($${2}))
}

defineReplace(qtConfFindFirstAvailableFeature) {
    for (feature, $$list($${1})) {
        isEmpty($${currentConfig}.features.$${feature}._KEYS_): \
            error("Asking for a report on undefined feature $${2}.")
        $$eval($${currentConfig}.features.$${feature}.available): \
            return($$eval($${currentConfig}.features.$${feature}.label))
    }

    return("<none>")
}

defineTest(qtConfReport_firstAvailableFeature) {
    qtConfReportPadded($${1}, $$qtConfFindFirstAvailableFeature($${2}))
}

defineTest(qtConfReport_feature) {
    !contains($${currentConfig}.features._KEYS_, $$2): \
        error("Asking for a report on undefined feature $${2}.")

    # hide report for not emitted features
    isEmpty($${currentConfig}.features.$${2}.available): \
        return()

    $$eval($${currentConfig}.features.$${2}.available) {
        result = "yes"
        !isEmpty(3): result = "$${3}"
    } else {
        result = "no"
        !isEmpty(4): result = "$${4}"
    }

    text = $$eval($${currentConfig}.features.$${2}.label)

    qtConfReportPadded($${1}$$text, $$result)
}

defineTest(qtConfReport_note) {
    qtConfAddNote($${1})
}

defineTest(qtConfReport_warning) {
    qtConfAddWarning($${1})
}

defineTest(qtConfReport_error) {
    qtConfAddError($${1}, log)
}

defineTest(qtConfReport_fatal) {
    qtConfFatalError($${1})
}

defineTest(qtConfCreateReportRecurse) {
    equals(2, false) {
        indent = ""
        recurse = false
    } else {
        indent = $${2}
        recurse = true
    }

    keys = $$eval($${1}._KEYS_)
    for (n, keys) {
        entry = $${1}.$$n
        subKeys = $$eval($${entry}._KEYS_)
        contains(subKeys, condition) {
            r = true
            for (condition, $$qtConfScalarOrList($${entry}.condition)) {
                r = $$qtConfEvaluate($$condition)
                !$$r: break()
            }
            !qtConfIsBoolean($$r): \
                error("Evaluation of condition '$$condition' in report entry $${entry} yielded non-boolean value '$$r'.")
            !$$r: next()
        }
        contains(subKeys, "section") {
            !$$recurse: \
                error("Report type 'section' is not allowed in '$$1'.")
            section = $$eval($${entry}.section)
            qtConfAddReport("$$indent$$section:")
            qtConfCreateReportRecurse("$${entry}.entries", "$$indent  ")
        } else: !isEmpty($${entry}) {
            feature = $$eval($${entry})
            qtConfReport_feature($$indent, $$feature)
        } else {
            text = $$eval($${entry}.message)
            isEmpty($${entry}.type): \
                error("Report entry $${entry} doesn't define a type.")
            r = "qtConfReport_$$eval($${entry}.type)"
            !defined($$r, test): \
                error("Undefined report type $$eval($${entry}.type) used in report entry $${entry}.")
            args = $$eval($${entry}.args)
            $${r}($$indent$${text}, $$args)
        }
    }
}

defineTest(qtConfProcessEarlyChecks) {
    qtConfCreateReportRecurse($${currentConfig}.earlyReport, false)
}

defineTest(qtConfCreateReport) {
    qtConfCreateReportRecurse($${currentConfig}.report, false)
}

defineTest(qtConfCreateSummary) {
    qtConfCreateReportRecurse($${currentConfig}.summary, "")
}

defineTest(qtConfPrintReport) {
    blocks = \
        "$$join(QT_CONFIGURE_REPORT, $$escape_expand(\\n))" \
        "$$join(QT_CONFIGURE_NOTES, $$escape_expand(\\n\\n))" \
        "$$join(QT_CONFIGURE_WARNINGS, $$escape_expand(\\n\\n))"

    !isEmpty(QT_CONFIGURE_ERRORS) {
        blocks += "$$join(QT_CONFIGURE_ERRORS, $$escape_expand(\\n\\n))"
        mention_config_log:!$$QMAKE_CONFIG_VERBOSE: \
            blocks += "Check config.log for details."
    }
    blocks = "$$join(blocks, $$escape_expand(\\n\\n))"
    logn($$blocks)
    !isEmpty(QT_CONFIGURE_ERRORS):!equals(config.input.continue, yes): \
        error()
    write_file($$OUT_PWD/config.summary, blocks)|error()
}

defineTest(qtConfCheckErrors) {
    !isEmpty(QT_CONFIGURE_ERRORS):!equals(config.input.continue, yes): \
        qtConfPrintReport()
}

#
# output generation
#

defineTest(qtConfOutput_libraryPaths) {
    qtLog("Global lib dirs: [$$val_escape(EXTRA_LIBDIR)] [$$val_escape(QMAKE_DEFAULT_LIBDIRS)]")
    qtLog("Global inc dirs: [$$val_escape(EXTRA_INCLUDEPATH)] [$$val_escape(QMAKE_DEFAULT_INCDIRS)]")
}

# qtConfOutputVar(modifier, output, name, value)
defineTest(qtConfOutputVar) {
    modifier = $$1
    output = $$2
    name = $$3
    value = $$val_escape(4)

    defined($${currentConfig}.output.$${output}.assign.$${name}, var): \
        error("Trying to overwrite assigned variable '$$name' in '$$output' using modifier '$$modifier'.")

    equals(modifier, assign) {
        !isEmpty($${currentConfig}.output.$${output}.append.$${name})|!isEmpty($${currentConfig}.output.$${output}.remove.$${name}): \
            error("Trying to assign variable '$$name' in '$$output', which has already appended or removed parts.")
        $${currentConfig}.output.$${output}.assign.$${name} = $$value
    } else: equals(modifier, append) {
        contains($${currentConfig}.output.$${output}.remove.$${name}, $$value): \
            error("Trying to append removed '$$value' to variable '$$name' in '$$output'.")
        $${currentConfig}.output.$${output}.append.$${name} += $$value
    } else: equals(modifier, remove) {
        contains($${currentConfig}.output.$${output}.append.$${name}, $$value): \
            error("Trying to remove appended '$$value' to variable '$$name' in '$$output'.")
        $${currentConfig}.output.$${output}.remove.$${name} += $$value
    } else {
        error("Invalid modifier '$$modifier' passed to qtConfOutputVar.")
    }
    $${currentConfig}.output.$${output}.$${modifier}._KEYS_ *= $${name}
    export($${currentConfig}.output.$${output}.$${modifier}.$${name})
    export($${currentConfig}.output.$${output}.$${modifier}._KEYS_)
}

# qtConfExtendVar(output, name, value)
defineTest(qtConfExtendVar) {
    output = $$1
    name = $$2
    value = $$val_escape(3)

    !defined($${currentConfig}.output.$${output}.assign.$${name}, var): \
        error("Trying to extend undefined variable '$$name' in '$$output'.")

    $${currentConfig}.output.$${output}.assign.$${name} += $$value
    export($${currentConfig}.output.$${output}.assign.$${name})
}

defineTest(qtConfOutputVarHelper) {
    !isEmpty($${2}.public):$$eval($${2}.public) {
        output = "publicPro"
    } else {
        output = "privatePro"
    }

    negative = $$eval($${2}.negative)
    isEmpty(negative): negative = false
    equals(3, $$negative): return()

    name = $$eval($${2}.name)
    isEmpty(name): \
        error("Output type 'var$$title($$1)' used in feature '$$eval($${2}.feature)' without a 'name' entry.")

    value = $$qtConfEvaluate($$eval($${2}.value))
    !isEmpty($${2}.eval):$$qtConfEvaluate($$eval($${2}.eval)): \
        eval(value = $$value)
    qtConfOutputVar($$1, $$output, $$name, $$value)
    equals(output, "publicPro"):!isEmpty($${currentConfig}.module): \
        qtConfExtendVar($$output, "QT.$${currentModule}.exports", $$name)
}

defineTest(qtConfOutput_varAssign) {
    qtConfOutputVarHelper(assign, $$1, $$2)
}

defineTest(qtConfOutput_varAppend) {
    qtConfOutputVarHelper(append, $$1, $$2)
}

defineTest(qtConfOutput_varRemove) {
    qtConfOutputVarHelper(remove, $$1, $$2)
}

defineTest(qtConfOutputConfigVar) {
    pro = $$3
    var = $$4
    modular = $$5

    negative = $$eval($${1}.negative)
    isEmpty(negative): negative = false
    equals(2, $$negative): return()

    val = $$eval($${1}.name)
    isEmpty(val) {
        val = $$eval($${1}.feature)
        $$negative: val = no-$$val
    }

    isEmpty($${currentConfig}.module)|!$$modular: \
        qtConfOutputVar(append, $$pro, $$var, $$val)
    else: \
        qtConfExtendVar($$pro, "QT.$${currentModule}.$$var", $$val)
}

defineTest(qtConfOutput_publicQtConfig) {
    qtConfOutputConfigVar($$1, $$2, "publicPro", "QT_CONFIG", true)
}

defineTest(qtConfOutput_publicConfig) {
    !isEmpty($${currentConfig}.module): \
        error("Cannot use output type 'publicConfig' in module-local feature '$$eval($${1}.feature)'.")
    qtConfOutputConfigVar($$1, $$2, "publicPro", "CONFIG", false)
}

defineTest(qtConfOutput_privateConfig) {
    qtConfOutputConfigVar($$1, $$2, "privatePro", "CONFIG", false)
}

defineTest(qtConfOutputSetDefine) {
    $${currentConfig}.output.$${1}.$${2} = $${3}
    $${currentConfig}.output.$${1}._KEYS_ *= $${2}
    export($${currentConfig}.output.$${1}.$${2})
    export($${currentConfig}.output.$${1}._KEYS_)
}

defineTest(qtConfOutput_define) {
    output = publicHeader
    define = $$eval($${1}.name)
    value = $$qtConfEvaluate($$eval($${1}.value))
    isEmpty(define): \
        error("Output type 'define' used in feature '$$eval($${1}.feature)' without a 'name' entry.")

    negative = $$eval($${1}.negative)
    isEmpty(negative): negative = false
    equals(2, $$negative): return()

    qtConfOutputSetDefine($$output, $$define, $$value)
}

defineTest(qtConfOutput_feature) {
    name = "$$eval($${1}.name)"
    isEmpty(name): \
        name = $$eval($${1}.feature)

    $${2} {
        isEmpty($${currentConfig}.module): \
            qtConfOutputVar(append, "publicPro", "QT_CONFIG", $$name)
        else: \
            qtConfExtendVar("publicPro", "QT.$${currentModule}.QT_CONFIG", $$name)
    } else {
        f = $$upper($$replace(name, -, _))
        qtConfOutputSetDefine("publicHeader", "QT_NO_$$f")
    }
}

defineTest(qtConfSetModuleName) {
    currentModule = $$eval($${currentConfig}.module)
    isEmpty(currentModule): \
        currentModule = global
    export(currentModule)
}

defineTest(qtConfSetupModuleOutputs) {
    qtConfOutputVar(assign, "publicPro", "QT.$${currentModule}.enabled_features", )
    qtConfOutputVar(assign, "publicPro", "QT.$${currentModule}.disabled_features", )
    qtConfOutputVar(assign, "privatePro", "QT.$${currentModule}_private.enabled_features", )
    qtConfOutputVar(assign, "privatePro", "QT.$${currentModule}_private.disabled_features", )
    !isEmpty($${currentConfig}.module) {
        qtConfOutputVar(assign, "publicPro", "QT.$${currentModule}.QT_CONFIG", )
        qtConfOutputVar(assign, "publicPro", "QT.$${currentModule}.exports", )
        qtConfOutputVar(assign, "privatePro", "QT.$${currentModule}_private.libraries", )
    }
}

defineTest(qtConfOutput_publicFeature) {
    name = "$$eval($${1}.name)"
    isEmpty(name): \
        name = $$eval($${1}.feature)
    feature = $$replace(name, [-+.], _)

    $${2} {
        qtConfExtendVar("publicPro", "QT.$${currentModule}.enabled_features", $$name)
        QT.$${currentModule}.enabled_features += $$name
        export(QT.$${currentModule}.enabled_features)
        qtConfOutputSetDefine("publicHeader", "QT_FEATURE_$$feature", 1)
    } else {
        qtConfExtendVar("publicPro", "QT.$${currentModule}.disabled_features", $$name)
        QT.$${currentModule}.disabled_features += $$name
        export(QT.$${currentModule}.disabled_features)
        qtConfOutputSetDefine("publicHeader", "QT_FEATURE_$$feature", -1)
    }
}

defineTest(qtConfOutput_privateFeature) {
    name = "$$eval($${1}.name)"
    isEmpty(name): \
        name = $$eval($${1}.feature)
    feature = $$replace(name, [-+.], _)

    $${2} {
        qtConfExtendVar("privatePro", "QT.$${currentModule}_private.enabled_features", $$name)
        QT.$${currentModule}_private.enabled_features += $$name
        export(QT.$${currentModule}_private.enabled_features)
        qtConfOutputSetDefine("privateHeader", "QT_FEATURE_$$feature", 1)
    } else {
        qtConfExtendVar("privatePro", "QT.$${currentModule}_private.disabled_features", $$name)
        QT.$${currentModule}_private.disabled_features += $$name
        export(QT.$${currentModule}_private.disabled_features)
        qtConfOutputSetDefine("privateHeader", "QT_FEATURE_$$feature", -1)
    }
}

defineTest(qtConfProcessOneOutput) {
    feature = $${1}
    fpfx = $${currentConfig}.features.$${feature}
    opfx = $${fpfx}.output.$${2}

    call = $$eval($${opfx}.type)
    isEmpty(call) {
        # output is just a string, not an object
        call = $$eval($$opfx)
    }
    !defined("qtConfOutput_$$call", test): \
        error("Undefined type '$$call' in output '$$2' of feature '$$feature'.")

    !$$qtConfEvaluate($$eval($${opfx}.condition)): \
        return()

    $${opfx}.feature = $$feature
    qtConfOutput_$${call}($$opfx, $$eval($${fpfx}.available))
}

defineTest(qtConfProcessOutput) {
    !contains($${currentConfig}._KEYS_, "features"): \
        return()

    basedir = $$shadowed($$eval($${currentConfig}.dir))
    module = $$eval($${currentConfig}.module)

    # write it to the output files
    !defined($${currentConfig}.files._KEYS_, var) {
        # set defaults that should work for most Qt modules
        isEmpty(module): \
            error("Neither module nor files section specified in configuration file.")

        $${currentConfig}.files._KEYS_ = publicPro privatePro publicHeader privateHeader
        $${currentConfig}.files.publicPro = qt$${module}-config.pri
        $${currentConfig}.files.privatePro = qt$${module}-config.pri  # sic!
        $${currentConfig}.files.publicHeader = qt$${module}-config.h
        $${currentConfig}.files.privateHeader = qt$${module}-config_p.h
    }

    for (type, $${currentConfig}.files._KEYS_) {
        contains(type, ".*Pro") {
            for (k, $${currentConfig}.output.$${type}.assign._KEYS_): \
                $${currentConfig}.output.$$type += "$$k = $$eval($${currentConfig}.output.$${type}.assign.$$k)"
            for (k, $${currentConfig}.output.$${type}.remove._KEYS_): \
                $${currentConfig}.output.$$type += "$$k -= $$eval($${currentConfig}.output.$${type}.remove.$$k)"
            for (k, $${currentConfig}.output.$${type}.append._KEYS_): \
                $${currentConfig}.output.$$type += "$$k += $$eval($${currentConfig}.output.$${type}.append.$$k)"
        } else: contains(type, ".*Header") {
            for (define, $${currentConfig}.output.$${type}._KEYS_) {
                value = $$eval($${currentConfig}.output.$${type}.$${define})
                $${currentConfig}.output.$$type += "$${LITERAL_HASH}define $$define $$value"
            }
        }

        content = $$eval($${currentConfig}.output.$${type})

        !isEmpty(module): \
            call = qtConfOutputPostProcess_$${module}_$${type}
        else: \
            call = qtConfOutputPostProcess_$${type}
        defined($$call, replace): \
            eval(content = \$\$"$$call"(\$\$content))

        file = $$eval($${currentConfig}.files.$${type})
        fileCont.$$file += $$content
        fileCont._KEYS_ *= $$file
    }

    for (file, fileCont._KEYS_): \
        write_file($$basedir/$$file, fileCont.$$file)|error()
}

#
# tie it all together
#

!isEmpty(_QMAKE_SUPER_CACHE_):!equals(OUT_PWD, $$dirname(_QMAKE_SUPER_CACHE_)) {
    # sub-repo within a top-level build; no need to configure anything.
    !isEmpty(QMAKE_EXTRA_ARGS) {
        # sub-projects don't get the extra args passed down automatically,
        # so we can use their presence to detect misguided attempts to
        # configure the repositories separately.
        # caveat: a plain qmake call is indistinguishable from a recursion
        # (by design), so we cannot detect this case.
        error("You cannot configure $$TARGET separately within a top-level build.")
    }
    return()
}

config.$${TARGET}.dir = $$_PRO_FILE_PWD_
cfgs = $$TARGET
!isEmpty(_QMAKE_SUPER_CACHE_) {
    for (s, SUBDIRS) {
        config.$${s}.dir = $$_PRO_FILE_PWD_/$${s}
        cfgs += $$s
    }
}
configsToProcess =
for (c, cfgs) {
    s = $$eval(config.$${c}.dir)
    exists($$s/configure.json): \
        configsToProcess += $$c
}
isEmpty(configsToProcess) {
    !isEmpty(QMAKE_EXTRA_ARGS): \
        error("This module does not accept configure command line arguments.")
    return()
}

load(configure_base)

QMAKE_POST_CONFIGURE =
config.builtins.dir = $$PWD/data
configsToProcess = builtins $$configsToProcess
allConfigs =
for(ever) {
    isEmpty(configsToProcess): \
        break()

    thisConfig = $$take_first(configsToProcess)
    currentConfig = config.$$thisConfig
    thisDir = $$eval($${currentConfig}.dir)
    jsonFile = $$thisDir/configure.json
    priFile = $$thisDir/configure.pri

    # load configuration data
    configure_data = $$cat($$jsonFile, blob)
    !parseJson(configure_data, $$currentConfig): \
        error("Invalid or non-existent file $${jsonFile}.")
    exists($$priFile): \
        !include($$priFile): error()

    # only configs which contain more than just subconfigs are saved for later.
    $${currentConfig}._KEYS_ -= subconfigs
    !isEmpty($${currentConfig}._KEYS_) {
        allConfigs += $$currentConfig
        contains($${currentConfig}._KEYS_, libraries) {
            qtConfSetupLibraries()
            # this ensures that references in QMAKE_LIBRARY_DEPS are unique.
            qtConfSetModuleName()
            ex = $$eval(config.modules.$${currentModule})
            !isEmpty(ex): \
                error("Module $$currentModule is claimed by both $$currentConfig and $${ex}.")
            config.modules.$${currentModule} = $$currentConfig
        }
    }

    # prepend all subconfigs to files to keep a depth first search order
    subconfigs =
    for(n, $${currentConfig}.subconfigs._KEYS_) {
        subconfig = $$eval($${currentConfig}.subconfigs.$${n})
        name = $${thisConfig}_$$basename(subconfig)
        ex = $$eval(config.$${name}.dir)
        !isEmpty(ex): \
            error("Basename clash between $$thisDir/$$subconfig and $${ex}.")
        config.$${name}.dir = $$thisDir/$$subconfig
        subconfigs += $$name
    }
    configsToProcess = $$subconfigs $$configsToProcess
}
# 'builtins' is used for command line parsing and test type dependency
# injection, but its features must not be processed regularly.
allModuleConfigs = $$member(allConfigs, 1, -1)

QMAKE_SAVED_ARGS = $$QMAKE_EXTRA_ARGS
QMAKE_REDO_CONFIG = false
qtConfParseCommandLine()
qtConfCheckErrors()

!isEmpty(config.input.list-features) {
    all_ft =
    for (currentConfig, allModuleConfigs) {
        for (k, $${currentConfig}.features._KEYS_) {
            pp = $$eval($${currentConfig}.features.$${k}.purpose)
            !isEmpty(pp) {
                pfx = $$eval($${currentConfig}.features.$${k}.section)
                !isEmpty(pfx): pfx = "$$pfx: "
                all_ft += $$qtConfPadCols($$k, ".......................", \
                                          $$pfx$$section(pp, $$escape_expand(\\n), 0, 0))
            }
        }
    }
    all_ft = $$sorted(all_ft)
    logn()
    for (ft, all_ft): \
        logn($$ft)
    error()
}

!isEmpty(config.input.list-libraries) {
    logn()
    for (currentConfig, allModuleConfigs) {
        !isEmpty($${currentConfig}.exports._KEYS_) {
            !isEmpty($${currentConfig}.module): \
                logn($$eval($${currentConfig}.module):)
            else: \
                logn($$section(currentConfig, ., -1):)
            all_xp =
            for (xport, $${currentConfig}.exports._KEYS_) {
                libs = $$eval($${currentConfig}.exports.$$xport)
                isEqual($${currentConfig}.libraries.$$first(libs).export, "") {  # not isEmpty()!
                    !isEmpty(config.input.verbose): \
                        all_xp += "$$xport!"
                } else {
                    out = "$$xport"
                    !isEmpty(config.input.verbose):!isEqual(xport, $$libs): \
                        out += "($$libs)"
                    all_xp += "$$out"
                }
            }
            all_xp = $$sorted(all_xp)
            all_xp ~= s,^([^!]*)!$,(\\1),g
            for (xp, all_xp): \
                logn("  $$xp")
        }
    }
    error()
}

QMAKE_CONFIG_VERBOSE = $$eval(config.input.verbose)
isEmpty(QMAKE_CONFIG_VERBOSE): \
    QMAKE_CONFIG_VERBOSE = false
QMAKE_CONFIG_LOG = $$OUT_PWD/config.log
write_file($$QMAKE_CONFIG_LOG, "")
qtLog("Command line: $$qtSystemQuote($$QMAKE_SAVED_ARGS)")
$$QMAKE_REDO_CONFIG: \
    qtLog("config.opt: $$qtSystemQuote($$QMAKE_EXTRA_REDO_ARGS)")

for (currentConfig, allModuleConfigs) {
    qtConfSetModuleName()
    qtConfSetupModuleOutputs()
    # do early checks, mainly to validate the command line
    qtConfProcessEarlyChecks()
}
qtConfCheckErrors()

QMAKE_CONFIG_CACHE = $$OUT_PWD/config.cache
QMAKE_CONFIG_CACHE_USE = $$eval(config.input.cache_use)
cache_recheck = $$eval(config.input.cache_recheck)
equals(cache_recheck, yes) {
    QMAKE_CONFIG_CACHE_USE = positive
    cache_recheck =
}
isEmpty(QMAKE_CONFIG_CACHE_USE): \
    QMAKE_CONFIG_CACHE_USE = all
!equals(QMAKE_CONFIG_CACHE_USE, none) {
    include($$QMAKE_CONFIG_CACHE, , true)
    # this crudely determines when to discard the cache. this also catches the case
    # of no cache being there in the first place.
    !equals(cache.platform, $$[QMAKE_SPEC])|!equals(cache.xplatform, $$[QMAKE_XSPEC]) {
        QMAKE_CONFIG_CACHE_USE = none
    } else: !isEmpty(cache_recheck) {
        for (cr, $$list($$split(cache_recheck, ","))) {
            !isEmpty(cache.$${cr}._KEYS_) {
                cache.$${cr}._KEYS_ =
            } else {
                qtConfAddWarning("Attempting to discard non-cached result '$$cr'.")
            }
        }
    }
}
equals(QMAKE_CONFIG_CACHE_USE, none) {
    cont = \
        "cache.platform = $$[QMAKE_SPEC]" \
        "cache.xplatform = $$[QMAKE_XSPEC]"
    write_file($$QMAKE_CONFIG_CACHE, cont)
}

CONFIG += qt_conf_tests_allowed
logn()
logn("Running configuration tests...")

for (currentConfig, allModuleConfigs) {
    tdir = $$eval($${currentConfig}.testDir)
    isEmpty(tdir): tdir = config.tests
    QMAKE_CONFIG_TESTS_DIR = $$absolute_path($$tdir, $$eval($${currentConfig}.dir))

    qtConfSetModuleName()

    qtConfSetupTestTypeDeps()

    # correctly setup dependencies
    QMAKE_CONFIG_DEPS = global global_private
    QMAKE_LIBRARY_DEPS = $$eval(config.modules.global)
    !isEmpty($${currentConfig}.module) {
        for (d, $${currentConfig}.depends._KEYS_) {
            dep = $$replace($${currentConfig}.depends.$$d, -private$, _private)
            gdep = $$replace(dep, _private$, )
            dep *= $$gdep
            QMAKE_CONFIG_DEPS += $$dep
            !isEqual(gdep, $$dep): \  # libraries are in the private module.
                QMAKE_LIBRARY_DEPS += $$eval(config.modules.$$gdep)
        }
    }

    qtConfCheckModuleCondition()

    qtConfHaveModule($$currentModule) {
        # process all features
        qtConfProcessFeatures()
    } else {
        qtConfOutputVar(assign, "privatePro", "QT.$${currentModule}.skip", "true")
    }

    # generate files and reports
    qtConfProcessOutput()
    qtConfHaveModule($$currentModule) {
        qtConfCreateReport()
        qtConfCreateSummary()
    } else {
        QT_CONFIGURE_SKIPPED_MODULES += "    $$currentModule"
    }
}

!isEmpty(QT_CONFIGURE_SKIPPED_MODULES): \
    qtConfAddNote("The following modules are not being compiled in this configuration:" $$QT_CONFIGURE_SKIPPED_MODULES)

logn("Done running configuration tests.")
logn()

!$$QMAKE_REDO_CONFIG {
    write_file($$OUT_PWD/config.opt, QMAKE_SAVED_ARGS)|error()
}

# these come from the pri files loaded above.
for (p, QMAKE_POST_CONFIGURE): \
    eval($$p)

logn("Configure summary:")
logn()
qtConfPrintReport()

load(qt_prefix_build_check)

# final notes for the user
logn()
logn("Qt is now configured for building. Just run '$$QMAKE_MAKE_NAME'.")
pfx = $$[QT_INSTALL_PREFIX]
qtIsPrefixBuild($$pfx) {
    logn("Once everything is built, you must run '$$QMAKE_MAKE_NAME install'.")
    logn("Qt will be installed into '$$system_path($$pfx)'.")
} else {
    logn("Once everything is built, Qt is installed.")
    logn("You should NOT run '$$QMAKE_MAKE_NAME install'.")
    logn("Note that this build cannot be deployed to other machines or devices.")
}
logn()
logn("Prior to reconfiguration, make sure you remove any leftovers from")
logn("the previous build.")
logn()
