
defineReplace(qtPlatformTargetSuffix) {
    suffix =
    CONFIG(debug, debug|release) {
        !debug_and_release|build_pass {
            mac: return($${suffix}_debug)
            win32: return($${suffix}d)
        }
    }
    return($$suffix)
}

defineReplace(qtLibraryTarget) {
   LIBRARY_NAME = $$1
   CONFIG(shared, static|shared):qtConfig(framework) {
      QMAKE_FRAMEWORK_BUNDLE_NAME = $$LIBRARY_NAME
      export(QMAKE_FRAMEWORK_BUNDLE_NAME)
   }
   return($$LIBRARY_NAME$$qtPlatformTargetSuffix())
}

defineReplace(qt5LibraryTarget) {
   LIBRARY_NAME = $$qtLibraryTarget($$1)
   isEmpty(QMAKE_FRAMEWORK_BUNDLE_NAME) {
       # Insert the major version of Qt in the library name
       # unless it's a framework build.
       LIBRARY_NAME ~= s,^Qt,Qt$$QT_MAJOR_VERSION,
   }
   return($$LIBRARY_NAME)
}

defineReplace(qtRelativeRPathBase) {
    darwin {
        if(equals(TEMPLATE, app):app_bundle)|\
                if(equals(TEMPLATE, lib):plugin:plugin_bundle) {
            shallow_bundle: return($$target.path/$${TARGET}.app)
            return($$target.path/$${TARGET}.app/Contents/MacOS)
        }
        equals(TEMPLATE, lib):!plugin:lib_bundle {
            shallow_bundle: return($$target.path/$${TARGET}.framework)
            return($$target.path/$${TARGET}.framework/Versions/Current)
        }
    }
    return($$target.path)
}

defineTest(qtAddLibrary) {
    warning("qtAddLibrary() is deprecated. Use QT+= instead.")

    # Reverse-engineer the module name from the library name.
    for(var, QT_MODULES) {
        isEqual(QT.$${var}.name, $$1) {
            QT += $$var
            export(QT)
            return(true)
        }
    }
    error("No module matching library '$$1' found.")
}

# qt module
defineTest(qtHaveModule) {
    !isEmpty(QT.$$replace(1, -, _).name): \
        return(true)
    return(false)
}

# variable, default, [suffix for variable for system() use], [prepare primary variable for system() use]
defineTest(qtPrepareTool) {
    cmd = $$eval(QT_TOOL.$${2}.binary)
    isEmpty(cmd) {
        cmd = $$[QT_HOST_BINS/get]/$$2
        exists($${cmd}.pl) {
            $${1}_EXE = $${cmd}.pl
            cmd = perl -w $$system_path($${cmd}.pl)
        } else: contains(QMAKE_HOST.os, Windows) {
            $${1}_EXE = $${cmd}.exe
            cmd = $$system_path($${cmd}.exe)
        } else:contains(QMAKE_HOST.os, Darwin) {
            BUNDLENAME = $${cmd}.app/Contents/MacOS/$$2
            exists($$BUNDLENAME) {
                cmd = $$BUNDLENAME
            }
            $${1}_EXE = $$cmd
        } else {
            $${1}_EXE = $$cmd
        }
    } else {
        $${1}_EXE = $$last(cmd)
    }
    export($${1}_EXE)
    QT_TOOL_ENV += $$eval(QT_TOOL.$${2}.envvars)
    QT_TOOL_NAME = $$2
    !isEmpty(3)|!isEmpty(4) {
        $$1$$3 =
        for (arg, cmd): \
            $$1$$3 += $$system_quote($$arg)
        qtAddTargetEnv($$1$$3, QT_TOOL.$${2}.depends, system)
    }
    isEmpty(4) {
        $$1 =
        for (arg, cmd): \
            $$1 += $$shell_quote($$arg)
        qtAddTargetEnv($$1, QT_TOOL.$${2}.depends, )
    }
}

# target variable, list of env var names, [non-empty: prepare for system(), not make]
defineTest(qtAddToolEnv) {
    isEmpty(3): \
        ds = $$QMAKE_DIR_SEP
    else: \
        ds = $$DIR_SEPARATOR
    batch_sets =
    for(env, 2) {
        value = $$eval($${env}.value)
        !isEmpty(value) {
            name = $$eval($${env}.name)
            config = $$eval($${env}.CONFIG)
            equals(ds, /) {
                contains(config, prepend): infix = \${$$name:+:\$$$name}
                else: contains(config, always_prepend): infix = :\$$$name
                else: infix =
                # Under msys, this path is taken only in the non-system()
                # case, so using shell_quote() always works.
                batch_sets += \
                    "$$name=$$shell_quote($$join(value, :))$$infix" \
                    "export $$name"
            } else {
                value ~= s,\\^,^^^^,g
                value ~= s,!,^^!,g
                value ~= s,\\),^),g
                contains(config, prepend) {
                    batch_sets += \
                        "if defined $$name (" \
                        "    set $$name=$$join(value, ;);!$$name!" \
                        ") else (" \
                        "    set $$name=$$join(value, ;)" \
                        ")"
                } else: contains(config, always_prepend) {
                    batch_sets += "(set $$name=$$join(value, ;);!$$name!)"
                } else {
                    batch_sets += "(set $$name=$$join(value, ;))"
                }
            }
        }
    }
    !isEmpty(batch_sets) {
        batch_name = wrapper
        !isEmpty(QT_TOOL_NAME): batch_name = $${QT_TOOL_NAME}_wrapper
        cmd = $$eval($$1)
        !isEmpty(cmd): cmd = "$$cmd "
        equals(ds, /) {
            batch_name = $${batch_name}.sh
            batch_cont = \
                "$$LITERAL_HASH!/bin/sh" \
                $$batch_sets \
                "exec $$cmd\"$@\""
            # It would be nicer to use the '.' command (without 'exec' above),
            # but that doesn't set the positional arguments under (d)ash.
            $$1 =
        } else {
            batch_name = $${batch_name}.bat
            batch_cont = \
                "@echo off" \
                "SetLocal EnableDelayedExpansion" \
                $$batch_sets \
                "$$cmd%*" \
                "EndLocal"
            $$1 = call
        }
        !build_pass:!write_file($$OUT_PWD/$$batch_name, batch_cont, exe): error()
        isEmpty(3): \
            $$1 += $$shell_quote($$shell_path($$OUT_PWD/$$batch_name))
        else: \
            $$1 += $$system_quote($$system_path($$OUT_PWD/$$batch_name))
        QMAKE_DISTCLEAN += $$OUT_PWD/$$batch_name
    }
    export($$1)
    export(QMAKE_DISTCLEAN)
}

# target variable, dependency var name, [non-empty: prepare for system(), not make]
defineTest(qtAddTargetEnv) {
    deps = $$replace($$2, -private$, _private)
    deps = $$resolve_depends(deps, "QT.", ".depends" ".run_depends")
    !isEmpty(deps) {
        libs = libs
        deppath.CONFIG = prepend
        equals(QMAKE_HOST.os, Windows) {
            libs = bins
            deppath.CONFIG = always_prepend
            deppath.name = PATH
        } else:contains(QMAKE_HOST.os, Linux|FreeBSD|OpenBSD|NetBSD|DragonFly|SunOS|HP-UX|QNX|GNU) {
            deppath.name = LD_LIBRARY_PATH
        } else:contains(QMAKE_HOST.os, Haiku) {
            deppath.name = LIBRARY_PATH
        } else:equals(QMAKE_HOST.os, Darwin) {
            qtConfig(framework): \
                deppath.name = DYLD_FRAMEWORK_PATH
            else: \
                deppath.name = DYLD_LIBRARY_PATH
        } else:equals(QMAKE_HOST.os, AIX) {
            deppath.name = LIBPATH
        } else {
            error("Operating system not supported.")
        }
        ptypes =
        for(dep, deps) {
            isEmpty(3): \
                deppath += $$shell_path($$eval(QT.$${dep}.$$libs))
            else: \
                deppath += $$system_path($$eval(QT.$${dep}.$$libs))
            ptypes += $$eval(QT.$${dep}.plugin_types)
        }
        deppath.value = $$unique(deppath)

        pluginpath.value =
        ppaths = $$[QT_INSTALL_PLUGINS/get]
        for(qplug, QT_PLUGINS): \
            contains(ptypes, $$eval(QT_PLUGIN.$${qplug}.TYPE)): \
                ppaths += $$eval(QT_PLUGIN.$${qplug}.PATH)
        ppaths = $$unique(ppaths)
        for(qplug, ppaths) {
            isEmpty(3): \
                pluginpath.value += $$shell_path($$qplug)
            else: \
                pluginpath.value += $$system_path($$qplug)
        }
        pluginpath.name = QT_PLUGIN_PATH
        pluginpath.CONFIG = prepend

        QT_TOOL_ENV += deppath pluginpath
    }
    qtAddToolEnv($$1, $$QT_TOOL_ENV, $$3)
}

defineReplace(pkgConfigExecutable) {
    isEmpty(PKG_CONFIG) {
        !isEmpty(QMAKE_PKG_CONFIG) {
            # Assumed to be properly sysrootified.
            PKG_CONFIG = $$QMAKE_PKG_CONFIG
            export(PKG_CONFIG)
        } else {
            PKG_CONFIG = pkg-config
            !cross_compile {
                export(PKG_CONFIG)
            } else {
                # Cross compiling, ensure that pkg-config is set up sanely.
                sysroot = $$[QT_SYSROOT]

                pkgConfigLibdir = $$(PKG_CONFIG_LIBDIR)
                isEmpty(pkgConfigLibdir) {
                    isEmpty(sysroot) {
                        warning("Cross compiling without sysroot. Disabling pkg-config.")
                        return()
                    }
                    !exists("$$sysroot/usr/lib/pkgconfig") {
                        warning("Disabling pkg-config since PKG_CONFIG_LIBDIR is not set and the")
                        warning("host's .pc files would be used (even if you set PKG_CONFIG_PATH).")
                        warning("Set this variable to the directory that contains target .pc files")
                        warning("for pkg-config to function correctly when cross-compiling.")
                        return()
                    }

                    pkgConfigLibdir = $$system_path($$sysroot/usr/lib/pkgconfig)$$QMAKE_DIRLIST_SEP$$system_path($$sysroot/usr/share/pkgconfig)
                    !isEmpty(GCC_MACHINE_DUMP): \
                        pkgConfigLibdir = "$$pkgConfigLibdir$$QMAKE_DIRLIST_SEP$$system_path($$sysroot/usr/lib/$$GCC_MACHINE_DUMP/pkgconfig)"
                    message("PKG_CONFIG_LIBDIR automatically set to $$pkgConfigLibdir")
                }
                pkgConfigSysrootDir = $$(PKG_CONFIG_SYSROOT_DIR)
                isEmpty(pkgConfigSysrootDir) {
                    isEmpty(sysroot) {
                        warning("Disabling pkg-config since PKG_CONFIG_SYSROOT_DIR is not set.")
                        warning("Set this variable to your sysroot for pkg-config to function")
                        warning("correctly when cross-compiling.")
                        return()
                    }

                    pkgConfigSysrootDir = $$sysroot
                    message("PKG_CONFIG_SYSROOT_DIR automatically set to $$pkgConfigSysrootDir")
                }

                sysroot.name = PKG_CONFIG_SYSROOT_DIR
                sysroot.value = $$pkgConfigSysrootDir
                libdir.name = PKG_CONFIG_LIBDIR
                libdir.value = $$pkgConfigLibdir
                QT_TOOL_NAME = pkg-config
                qtAddToolEnv(PKG_CONFIG, sysroot libdir, SYS)
            }
        }
    }

    PKG_CONFIG += 2> $$QMAKE_SYSTEM_NULL_DEVICE

    return($$PKG_CONFIG)
}

defineTest(packagesExist) {
    # this can't be done in global scope here because qt_functions is loaded
    # before the .pro is parsed, so if the .pro set PKG_CONFIG, we wouldn't know it
    # yet. oops.
    pkg_config = $$pkgConfigExecutable()

    for(package, ARGS) {
        !system($$pkg_config --exists $$package):return(false)
    }

    return(true)
}

# Prepares target that will iterate through all subdirs (except those
# with no_default_target or no_{name_of_target}_target. The prepared
# target must still be manually added to QMAKE_EXTRA_TARGETS.
defineTest(prepareRecursiveTarget) {
    target = $$1
    no_$${target}_target: return()

    for(subdir, SUBDIRS) {
        subdir_config = $$eval($${subdir}.CONFIG)
        contains(subdir_config, no_default_target): next()
        contains(subdir_config, no_$${target}_target): next()

        $${target}.recurse += $$subdir
    }

    # Set up the recurse target only when there
    # is something to recurse into.
    isEmpty($${target}.recurse): return()

    $${target}.CONFIG = recursive
    $${target}.recurse_target = $${target}

    export($${target}.recurse)
    export($${target}.CONFIG)
    export($${target}.recurse_target)
}

defineTest(qtConfig) {
    modules = $$QT $$QT_PRIVATE $$QT_FOR_CONFIG
    modules ~= s,-private$,_private,g
    modules = $$resolve_depends(modules, "QT.", ".depends")
    modules += global global_private
    modules = $$reverse(modules)
    for (module, modules) {
        contains(QT.$${module}.enabled_features, $$1): \
            return(true)
        contains(QT.$${module}.disabled_features, $$1): \
            return(false)
    }
    error("Could not find feature $${1}.")
}
