/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "utils.h"
#include "qmlutils.h"

#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QCoreApplication>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonArray>
#include <QtCore/QCommandLineParser>
#include <QtCore/QCommandLineOption>
#include <QtCore/QOperatingSystemVersion>
#include <QtCore/QSharedPointer>
#include <QtCore/QVector>

#ifdef Q_OS_WIN
#include <QtCore/qt_windows.h>
#else
#define IMAGE_FILE_MACHINE_ARM64 0xaa64
#endif

#include <algorithm>
#include <iostream>
#include <cstdio>

QT_BEGIN_NAMESPACE

enum QtModule
#if defined(Q_COMPILER_CLASS_ENUM) || defined(Q_CC_MSVC)
    : quint64
#endif
{
    QtBluetoothModule         = 0x0000000000000001,
    QtConcurrentModule        = 0x0000000000000002,
    QtCoreModule              = 0x0000000000000004,
    QtDeclarativeModule       = 0x0000000000000008,
    QtDesignerComponents      = 0x0000000000000010,
    QtDesignerModule          = 0x0000000000000020,
    QtGuiModule               = 0x0000000000000040,
    QtHelpModule              = 0x0000000000000080,
    QtMultimediaModule        = 0x0000000000000100,
    QtMultimediaWidgetsModule = 0x0000000000000200,
    QtMultimediaQuickModule   = 0x0000000000000400,
    QtNetworkModule           = 0x0000000000000800,
    QtNfcModule               = 0x0000000000001000,
    QtOpenGLModule            = 0x0000000000002000,
    QtPositioningModule       = 0x0000000000004000,
    QtPrintSupportModule      = 0x0000000000008000,
    QtQmlModule               = 0x0000000000010000,
    QtQuickModule             = 0x0000000000020000,
    QtQuickParticlesModule    = 0x0000000000040000,
    QtScriptModule            = 0x0000000000080000,
    QtScriptToolsModule       = 0x0000000000100000,
    QtSensorsModule           = 0x0000000000200000,
    QtSerialPortModule        = 0x0000000000400000,
    QtSqlModule               = 0x0000000000800000,
    QtSvgModule               = 0x0000000001000000,
    QtTestModule              = 0x0000000002000000,
    QtWidgetsModule           = 0x0000000004000000,
    QtWinExtrasModule         = 0x0000000008000000,
    QtXmlModule               = 0x0000000010000000,
    QtXmlPatternsModule       = 0x0000000020000000,
    QtWebKitModule            = 0x0000000040000000,
    QtWebKitWidgetsModule     = 0x0000000080000000,
    QtQuickWidgetsModule      = 0x0000000100000000,
    QtWebSocketsModule        = 0x0000000200000000,
    QtEnginioModule           = 0x0000000400000000,
    QtWebEngineCoreModule     = 0x0000000800000000,
    QtWebEngineModule         = 0x0000001000000000,
    QtWebEngineWidgetsModule  = 0x0000002000000000,
    QtQmlToolingModule        = 0x0000004000000000,
    Qt3DCoreModule            = 0x0000008000000000,
    Qt3DRendererModule        = 0x0000010000000000,
    Qt3DQuickModule           = 0x0000020000000000,
    Qt3DQuickRendererModule   = 0x0000040000000000,
    Qt3DInputModule           = 0x0000080000000000,
    QtLocationModule          = 0x0000100000000000,
    QtWebChannelModule        = 0x0000200000000000,
    QtTextToSpeechModule      = 0x0000400000000000,
    QtSerialBusModule         = 0x0000800000000000,
    QtGamePadModule           = 0x0001000000000000,
    Qt3DAnimationModule       = 0x0002000000000000,
    QtWebViewModule           = 0x0004000000000000,
    Qt3DExtrasModule          = 0x0008000000000000
};

struct QtModuleEntry {
    quint64 module;
    const char *option;
    const char *libraryName;
    const char *translation;
};

static QtModuleEntry qtModuleEntries[] = {
    { QtBluetoothModule, "bluetooth", "Qt5Bluetooth", nullptr },
    { QtConcurrentModule, "concurrent", "Qt5Concurrent", "qtbase" },
    { QtCoreModule, "core", "Qt5Core", "qtbase" },
    { QtDeclarativeModule, "declarative", "Qt5Declarative", "qtquick1" },
    { QtDesignerModule, "designer", "Qt5Designer", nullptr },
    { QtDesignerComponents, "designercomponents", "Qt5DesignerComponents", nullptr },
    { QtEnginioModule, "enginio", "Enginio", nullptr },
    { QtGamePadModule, "gamepad", "Qt5Gamepad", nullptr },
    { QtGuiModule, "gui", "Qt5Gui", "qtbase" },
    { QtHelpModule, "qthelp", "Qt5Help", "qt_help" },
    { QtMultimediaModule, "multimedia", "Qt5Multimedia", "qtmultimedia" },
    { QtMultimediaWidgetsModule, "multimediawidgets", "Qt5MultimediaWidgets", "qtmultimedia" },
    { QtMultimediaQuickModule, "multimediaquick", "Qt5MultimediaQuick_p", "qtmultimedia" },
    { QtNetworkModule, "network", "Qt5Network", "qtbase" },
    { QtNfcModule, "nfc", "Qt5Nfc", nullptr },
    { QtOpenGLModule, "opengl", "Qt5OpenGL", nullptr },
    { QtPositioningModule, "positioning", "Qt5Positioning", nullptr },
    { QtPrintSupportModule, "printsupport", "Qt5PrintSupport", nullptr },
    { QtQmlModule, "qml", "Qt5Qml", "qtdeclarative" },
    { QtQmlToolingModule, "qmltooling", "qmltooling", nullptr },
    { QtQuickModule, "quick", "Qt5Quick", "qtdeclarative" },
    { QtQuickParticlesModule, "quickparticles", "Qt5QuickParticles", nullptr },
    { QtQuickWidgetsModule, "quickwidgets", "Qt5QuickWidgets", nullptr },
    { QtScriptModule, "script", "Qt5Script", "qtscript" },
    { QtScriptToolsModule, "scripttools", "Qt5ScriptTools", "qtscript" },
    { QtSensorsModule, "sensors", "Qt5Sensors", nullptr },
    { QtSerialPortModule, "serialport", "Qt5SerialPort", "qtserialport" },
    { QtSqlModule, "sql", "Qt5Sql", "qtbase" },
    { QtSvgModule, "svg", "Qt5Svg", nullptr },
    { QtTestModule, "test", "Qt5Test", "qtbase" },
    { QtWebKitModule, "webkit", "Qt5WebKit", nullptr },
    { QtWebKitWidgetsModule, "webkitwidgets", "Qt5WebKitWidgets", nullptr },
    { QtWebSocketsModule, "websockets", "Qt5WebSockets", nullptr },
    { QtWidgetsModule, "widgets", "Qt5Widgets", "qtbase" },
    { QtWinExtrasModule, "winextras", "Qt5WinExtras", nullptr },
    { QtXmlModule, "xml", "Qt5Xml", "qtbase" },
    { QtXmlPatternsModule, "xmlpatterns", "Qt5XmlPatterns", "qtxmlpatterns" },
    { QtWebEngineCoreModule, "webenginecore", "Qt5WebEngineCore", nullptr },
    { QtWebEngineModule, "webengine", "Qt5WebEngine", "qtwebengine" },
    { QtWebEngineWidgetsModule, "webenginewidgets", "Qt5WebEngineWidgets", nullptr },
    { Qt3DCoreModule, "3dcore", "Qt53DCore", nullptr },
    { Qt3DRendererModule, "3drenderer", "Qt53DRender", nullptr },
    { Qt3DQuickModule, "3dquick", "Qt53DQuick", nullptr },
    { Qt3DQuickRendererModule, "3dquickrenderer", "Qt53DQuickRender", nullptr },
    { Qt3DInputModule, "3dinput", "Qt53DInput", nullptr },
    { Qt3DAnimationModule, "3danimation", "Qt53DAnimation", nullptr },
    { Qt3DExtrasModule, "3dextras", "Qt53DExtras", nullptr },
    { QtLocationModule, "geoservices", "Qt5Location", nullptr },
    { QtWebChannelModule, "webchannel", "Qt5WebChannel", nullptr },
    { QtTextToSpeechModule, "texttospeech", "Qt5TextToSpeech", nullptr },
    { QtSerialBusModule, "serialbus", "Qt5SerialBus", nullptr },
    { QtWebViewModule, "webview", "Qt5WebView", nullptr }
};

enum QtPlugin {
    QtVirtualKeyboardPlugin = 0x1
};

static const char webKitProcessC[] = "QtWebProcess";
static const char webEngineProcessC[] = "QtWebEngineProcess";

static inline QString webProcessBinary(const char *binaryName, Platform p)
{
    const QString webProcess = QLatin1String(binaryName);
    return (p & WindowsBased) ? webProcess + QStringLiteral(".exe") : webProcess;
}

static QByteArray formatQtModules(quint64 mask, bool option = false)
{
    QByteArray result;
    for (const auto &qtModule : qtModuleEntries) {
        if (mask & qtModule.module) {
            if (!result.isEmpty())
                result.append(' ');
            result.append(option ? qtModule.option : qtModule.libraryName);
        }
    }
    return result;
}

static Platform platformFromMkSpec(const QString &xSpec)
{
    if (xSpec == QLatin1String("linux-g++"))
        return Unix;
    if (xSpec.startsWith(QLatin1String("win32-"))) {
        if (xSpec.contains(QLatin1String("clang-g++")))
            return WindowsDesktopClangMinGW;
        if (xSpec.contains(QLatin1String("clang-msvc++")))
            return WindowsDesktopClangMsvc;
        return xSpec.contains(QLatin1String("g++")) ? WindowsDesktopMinGW : WindowsDesktopMsvc;
    }
    if (xSpec.startsWith(QLatin1String("winrt-x")))
        return WinRtIntelMsvc;
    if (xSpec.startsWith(QLatin1String("winrt-arm")))
        return WinRtArmMsvc;
    return UnknownPlatform;
}

// Helpers for exclusive options, "-foo", "--no-foo"
enum ExlusiveOptionValue {
    OptionAuto,
    OptionEnabled,
    OptionDisabled
};

static ExlusiveOptionValue parseExclusiveOptions(const QCommandLineParser *parser,
                                                 const QCommandLineOption &enableOption,
                                                 const QCommandLineOption &disableOption)
{
    const bool enabled = parser->isSet(enableOption);
    const bool disabled = parser->isSet(disableOption);
    if (enabled) {
        if (disabled) {
            std::wcerr << "Warning: both -" << enableOption.names().first()
                << " and -" << disableOption.names().first() << " were specified, defaulting to -"
                << enableOption.names().first() << ".\n";
        }
        return OptionEnabled;
    }
    return disabled ? OptionDisabled : OptionAuto;
}

static ExlusiveOptionValue optWebKit2 = OptionAuto;

struct Options {
    enum DebugDetection {
        DebugDetectionAuto,
        DebugDetectionForceDebug,
        DebugDetectionForceRelease
    };

    enum AngleDetection {
        AngleDetectionAuto,
        AngleDetectionForceOn,
        AngleDetectionForceOff
    };

    bool plugins = true;
    bool libraries = true;
    bool quickImports = true;
    bool translations = true;
    bool systemD3dCompiler = true;
    bool compilerRunTime = false;
    unsigned disabledPlugins = 0;
    AngleDetection angleDetection = AngleDetectionAuto;
    bool softwareRasterizer = true;
    Platform platform = WindowsDesktopMsvc;
    quint64 additionalLibraries = 0;
    quint64 disabledLibraries = 0;
    unsigned updateFileFlags = 0;
    QStringList qmlDirectories; // Project's QML files.
    QStringList qmlImportPaths; // Custom QML module locations.
    QString directory;
    QString translationsDirectory; // Translations target directory
    QStringList languages;
    QString libraryDirectory;
    QString pluginDirectory;
    QStringList binaries;
    JsonOutput *json = nullptr;
    ListOption list = ListNone;
    DebugDetection debugDetection = DebugDetectionAuto;
    bool deployPdb = false;
    bool dryRun = false;
    bool patchQt = true;
    bool ignoreLibraryErrors = false;

    inline bool isWinRt() const { return platform.testFlag(WinRt); }
};

// Return binary from folder
static inline QString findBinary(const QString &directory, Platform platform)
{
    const QStringList nameFilters = (platform & WindowsBased) ?
        QStringList(QStringLiteral("*.exe")) : QStringList();
    const QFileInfoList &binaries =
        QDir(QDir::cleanPath(directory)).entryInfoList(nameFilters, QDir::Files | QDir::Executable);
    for (const QFileInfo &binaryFi : binaries) {
        const QString binary = binaryFi.fileName();
        if (!binary.contains(QLatin1String(webKitProcessC), Qt::CaseInsensitive)
            && !binary.contains(QLatin1String(webEngineProcessC), Qt::CaseInsensitive)) {
            return binaryFi.absoluteFilePath();
        }
    }
    return QString();
}

static QString msgFileDoesNotExist(const QString & file)
{
    return QLatin1Char('"') + QDir::toNativeSeparators(file)
        + QStringLiteral("\" does not exist.");
}

enum CommandLineParseFlag {
    CommandLineParseError = 0x1,
    CommandLineParseHelpRequested = 0x2
};

static inline int parseArguments(const QStringList &arguments, QCommandLineParser *parser,
                                 Options *options, QString *errorMessage)
{
    using CommandLineOptionPtr = QSharedPointer<QCommandLineOption>;
    using OptionPtrVector = QVector<CommandLineOptionPtr>;

    parser->setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
    parser->setApplicationDescription(QStringLiteral("Qt Deploy Tool ") + QLatin1String(QT_VERSION_STR)
        + QLatin1String("\n\nThe simplest way to use windeployqt is to add the bin directory of your Qt\n"
        "installation (e.g. <QT_DIR\\bin>) to the PATH variable and then run:\n  windeployqt <path-to-app-binary>\n"
        "If ICU, ANGLE, etc. are not in the bin directory, they need to be in the PATH\nvariable. "
        "If your application uses Qt Quick, run:\n  windeployqt --qmldir <path-to-app-qml-files> <path-to-app-binary>"));
    const QCommandLineOption helpOption = parser->addHelpOption();
    parser->addVersionOption();

    QCommandLineOption dirOption(QStringLiteral("dir"),
                                 QStringLiteral("Use directory instead of binary directory."),
                                 QStringLiteral("directory"));
    parser->addOption(dirOption);

    QCommandLineOption libDirOption(QStringLiteral("libdir"),
                                    QStringLiteral("Copy libraries to path."),
                                    QStringLiteral("path"));
    parser->addOption(libDirOption);

    QCommandLineOption pluginDirOption(QStringLiteral("plugindir"),
                                       QStringLiteral("Copy plugins to path."),
                                       QStringLiteral("path"));
    parser->addOption(pluginDirOption);

    QCommandLineOption debugOption(QStringLiteral("debug"),
                                   QStringLiteral("Assume debug binaries."));
    parser->addOption(debugOption);
    QCommandLineOption releaseOption(QStringLiteral("release"),
                                   QStringLiteral("Assume release binaries."));
    parser->addOption(releaseOption);
    QCommandLineOption releaseWithDebugInfoOption(QStringLiteral("release-with-debug-info"),
                                                  QStringLiteral("Assume release binaries with debug information."));
    releaseWithDebugInfoOption.setFlags(QCommandLineOption::HiddenFromHelp); // Deprecated by improved debug detection.
    parser->addOption(releaseWithDebugInfoOption);

    QCommandLineOption deployPdbOption(QStringLiteral("pdb"),
                                       QStringLiteral("Deploy .pdb files (MSVC)."));
    parser->addOption(deployPdbOption);

    QCommandLineOption forceOption(QStringLiteral("force"),
                                    QStringLiteral("Force updating files."));
    parser->addOption(forceOption);

    QCommandLineOption dryRunOption(QStringLiteral("dry-run"),
                                    QStringLiteral("Simulation mode. Behave normally, but do not copy/update any files."));
    parser->addOption(dryRunOption);

    QCommandLineOption noPatchQtOption(QStringLiteral("no-patchqt"),
                                       QStringLiteral("Do not patch the Qt5Core library."));
    parser->addOption(noPatchQtOption);

    QCommandLineOption ignoreErrorOption(QStringLiteral("ignore-library-errors"),
                                         QStringLiteral("Ignore errors when libraries cannot be found."));
    parser->addOption(ignoreErrorOption);

    QCommandLineOption noPluginsOption(QStringLiteral("no-plugins"),
                                       QStringLiteral("Skip plugin deployment."));
    parser->addOption(noPluginsOption);

    QCommandLineOption noLibraryOption(QStringLiteral("no-libraries"),
                                       QStringLiteral("Skip library deployment."));
    parser->addOption(noLibraryOption);

    QCommandLineOption qmlDirOption(QStringLiteral("qmldir"),
                                    QStringLiteral("Scan for QML-imports starting from directory."),
                                    QStringLiteral("directory"));
    parser->addOption(qmlDirOption);

    QCommandLineOption qmlImportOption(QStringLiteral("qmlimport"),
                                       QStringLiteral("Add the given path to the QML module search locations."),
                                       QStringLiteral("directory"));
    parser->addOption(qmlImportOption);

    QCommandLineOption noQuickImportOption(QStringLiteral("no-quick-import"),
                                           QStringLiteral("Skip deployment of Qt Quick imports."));
    parser->addOption(noQuickImportOption);


    QCommandLineOption translationOption(QStringLiteral("translations"),
                                         QStringLiteral("A comma-separated list of languages to deploy (de,fi)."),
                                         QStringLiteral("languages"));
    parser->addOption(translationOption);

    QCommandLineOption noTranslationOption(QStringLiteral("no-translations"),
                                           QStringLiteral("Skip deployment of translations."));
    parser->addOption(noTranslationOption);

    QCommandLineOption noSystemD3DCompilerOption(QStringLiteral("no-system-d3d-compiler"),
                                                 QStringLiteral("Skip deployment of the system D3D compiler."));
    parser->addOption(noSystemD3DCompilerOption);


    QCommandLineOption compilerRunTimeOption(QStringLiteral("compiler-runtime"),
                                             QStringLiteral("Deploy compiler runtime (Desktop only)."));
    parser->addOption(compilerRunTimeOption);

    QCommandLineOption noVirtualKeyboardOption(QStringLiteral("no-virtualkeyboard"),
                                               QStringLiteral("Disable deployment of the Virtual Keyboard."));
    parser->addOption(noVirtualKeyboardOption);

    QCommandLineOption noCompilerRunTimeOption(QStringLiteral("no-compiler-runtime"),
                                             QStringLiteral("Do not deploy compiler runtime (Desktop only)."));
    parser->addOption(noCompilerRunTimeOption);

    QCommandLineOption webKitOption(QStringLiteral("webkit2"),
                                    QStringLiteral("Deployment of WebKit2 (web process)."));
    parser->addOption(webKitOption);

    QCommandLineOption noWebKitOption(QStringLiteral("no-webkit2"),
                                      QStringLiteral("Skip deployment of WebKit2."));
    parser->addOption(noWebKitOption);

    QCommandLineOption jsonOption(QStringLiteral("json"),
                                  QStringLiteral("Print to stdout in JSON format."));
    parser->addOption(jsonOption);

    QCommandLineOption angleOption(QStringLiteral("angle"),
                                   QStringLiteral("Force deployment of ANGLE."));
    parser->addOption(angleOption);

    QCommandLineOption noAngleOption(QStringLiteral("no-angle"),
                                     QStringLiteral("Disable deployment of ANGLE."));
    parser->addOption(noAngleOption);

    QCommandLineOption suppressSoftwareRasterizerOption(QStringLiteral("no-opengl-sw"),
                                                        QStringLiteral("Do not deploy the software rasterizer library."));
    parser->addOption(suppressSoftwareRasterizerOption);

    QCommandLineOption listOption(QStringLiteral("list"),
                                  QLatin1String("Print only the names of the files copied.\n"
                                                "Available options:\n"
                                                "  source:   absolute path of the source files\n"
                                                "  target:   absolute path of the target files\n"
                                                "  relative: paths of the target files, relative\n"
                                                "            to the target directory\n"
                                                "  mapping:  outputs the source and the relative\n"
                                                "            target, suitable for use within an\n"
                                                "            Appx mapping file"),
                                  QStringLiteral("option"));
    parser->addOption(listOption);

    QCommandLineOption verboseOption(QStringLiteral("verbose"),
                                     QStringLiteral("Verbose level (0-2)."),
                                     QStringLiteral("level"));
    parser->addOption(verboseOption);

    parser->addPositionalArgument(QStringLiteral("[files]"),
                                  QStringLiteral("Binaries or directory containing the binary."));

    OptionPtrVector enabledModuleOptions;
    OptionPtrVector disabledModuleOptions;
    const int qtModulesCount = int(sizeof(qtModuleEntries) / sizeof(QtModuleEntry));
    enabledModuleOptions.reserve(qtModulesCount);
    disabledModuleOptions.reserve(qtModulesCount);
    for (int i = 0; i < qtModulesCount; ++i) {
        const QString option = QLatin1String(qtModuleEntries[i].option);
        const QString name = QLatin1String(qtModuleEntries[i].libraryName);
        const QString enabledDescription = QStringLiteral("Add ") + name + QStringLiteral(" module.");
        CommandLineOptionPtr enabledOption(new QCommandLineOption(option, enabledDescription));
        parser->addOption(*enabledOption.data());
        enabledModuleOptions.append(enabledOption);
        const QString disabledDescription = QStringLiteral("Remove ") + name + QStringLiteral(" module.");
        CommandLineOptionPtr disabledOption(new QCommandLineOption(QStringLiteral("no-") + option,
                                                                   disabledDescription));
        disabledModuleOptions.append(disabledOption);
        parser->addOption(*disabledOption.data());
    }

    const bool success = parser->parse(arguments);
    if (parser->isSet(helpOption))
        return CommandLineParseHelpRequested;
    if (!success) {
        *errorMessage = parser->errorText();
        return CommandLineParseError;
    }

    options->libraryDirectory = parser->value(libDirOption);
    options->pluginDirectory = parser->value(pluginDirOption);
    options->plugins = !parser->isSet(noPluginsOption);
    options->libraries = !parser->isSet(noLibraryOption);
    options->translations = !parser->isSet(noTranslationOption);
    if (parser->isSet(translationOption))
        options->languages = parser->value(translationOption).split(QLatin1Char(','));
    options->systemD3dCompiler = !parser->isSet(noSystemD3DCompilerOption);
    options->quickImports = !parser->isSet(noQuickImportOption);

    if (parser->isSet(compilerRunTimeOption))
        options->compilerRunTime = true;
    else if (parser->isSet(noCompilerRunTimeOption))
        options->compilerRunTime = false;

    if (options->compilerRunTime && options->platform != WindowsDesktopMinGW && options->platform != WindowsDesktopMsvc) {
        *errorMessage = QStringLiteral("Deployment of the compiler runtime is implemented for Desktop MSVC/g++ only.");
        return CommandLineParseError;
    }

    if (parser->isSet(noVirtualKeyboardOption))
        options->disabledPlugins |= QtVirtualKeyboardPlugin;

    if (parser->isSet(releaseWithDebugInfoOption))
        std::wcerr << "Warning: " << releaseWithDebugInfoOption.names().first() << " is obsolete.";

    switch (parseExclusiveOptions(parser, debugOption, releaseOption)) {
    case OptionAuto:
        break;
    case OptionEnabled:
        options->debugDetection = Options::DebugDetectionForceDebug;
        break;
    case OptionDisabled:
        options->debugDetection = Options::DebugDetectionForceRelease;
        break;
    }

    if (parser->isSet(deployPdbOption)) {
        if (options->platform.testFlag(WindowsBased) && !options->platform.testFlag(MinGW))
            options->deployPdb = true;
        else
            std::wcerr << "Warning: --" << deployPdbOption.names().first() << " is not supported on this platform.\n";
    }

    switch (parseExclusiveOptions(parser, angleOption, noAngleOption)) {
    case OptionAuto:
        break;
    case OptionEnabled:
        options->angleDetection = Options::AngleDetectionForceOn;
        break;
    case OptionDisabled:
        options->angleDetection = Options::AngleDetectionForceOff;
        break;
    }

    if (parser->isSet(suppressSoftwareRasterizerOption))
        options->softwareRasterizer = false;

    optWebKit2 = parseExclusiveOptions(parser, webKitOption, noWebKitOption);

    if (parser->isSet(forceOption))
        options->updateFileFlags |= ForceUpdateFile;
    if (parser->isSet(dryRunOption)) {
        options->dryRun = true;
        options->updateFileFlags |= SkipUpdateFile;
    }

    options->patchQt = !parser->isSet(noPatchQtOption);
    options->ignoreLibraryErrors = parser->isSet(ignoreErrorOption);

    for (int i = 0; i < qtModulesCount; ++i) {
        if (parser->isSet(*enabledModuleOptions.at(i)))
            options->additionalLibraries |= qtModuleEntries[i].module;
        if (parser->isSet(*disabledModuleOptions.at(i)))
            options->disabledLibraries |= qtModuleEntries[i].module;
    }

    // Add some dependencies
    if (options->additionalLibraries & QtQuickModule)
        options->additionalLibraries |= QtQmlModule;
    if (options->additionalLibraries & QtDesignerComponents)
        options->additionalLibraries |= QtDesignerModule;

    if (parser->isSet(listOption)) {
        const QString value = parser->value(listOption);
        if (value == QStringLiteral("source")) {
            options->list = ListSource;
        } else if (value == QStringLiteral("target")) {
            options->list = ListTarget;
        } else if (value == QStringLiteral("relative")) {
            options->list = ListRelative;
        } else if (value == QStringLiteral("mapping")) {
            options->list = ListMapping;
        } else {
            *errorMessage = QStringLiteral("Please specify a valid option for -list (source, target, relative, mapping).");
            return CommandLineParseError;
        }
    }

    if (parser->isSet(jsonOption) || options->list) {
        optVerboseLevel = 0;
        options->json = new JsonOutput;
    } else {
        if (parser->isSet(verboseOption)) {
            bool ok;
            const QString value = parser->value(verboseOption);
            optVerboseLevel = value.toInt(&ok);
            if (!ok || optVerboseLevel < 0) {
                *errorMessage = QStringLiteral("Invalid value \"%1\" passed for verbose level.").arg(value);
                return CommandLineParseError;
            }
        }
    }

    const QStringList posArgs = parser->positionalArguments();
    if (posArgs.isEmpty()) {
        *errorMessage = QStringLiteral("Please specify the binary or folder.");
        return CommandLineParseError | CommandLineParseHelpRequested;
    }

    if (parser->isSet(dirOption))
        options->directory = parser->value(dirOption);

    if (parser->isSet(qmlDirOption))
        options->qmlDirectories = parser->values(qmlDirOption);

    if (parser->isSet(qmlImportOption))
        options->qmlImportPaths = parser->values(qmlImportOption);

    const QString &file = posArgs.front();
    const QFileInfo fi(QDir::cleanPath(file));
    if (!fi.exists()) {
        *errorMessage = msgFileDoesNotExist(file);
        return CommandLineParseError;
    }

    if (!options->directory.isEmpty() && !fi.isFile()) { // -dir was specified - expecting file.
        *errorMessage = QLatin1Char('"') + file + QStringLiteral("\" is not an executable file.");
        return CommandLineParseError;
    }

    if (fi.isFile()) {
        options->binaries.append(fi.absoluteFilePath());
        if (options->directory.isEmpty())
            options->directory = fi.absolutePath();
    } else {
        const QString binary = findBinary(fi.absoluteFilePath(), options->platform);
        if (binary.isEmpty()) {
            *errorMessage = QStringLiteral("Unable to find binary in \"") + file + QLatin1Char('"');
            return CommandLineParseError;
        }
        options->directory = fi.absoluteFilePath();
        options->binaries.append(binary);
    } // directory.

    // Remaining files or plugin directories
    for (int i = 1; i < posArgs.size(); ++i) {
        const QFileInfo fi(QDir::cleanPath(posArgs.at(i)));
        const QString path = fi.absoluteFilePath();
        if (!fi.exists()) {
            *errorMessage = msgFileDoesNotExist(path);
            return CommandLineParseError;
        }
        if (fi.isDir()) {
            const QStringList libraries =
                findSharedLibraries(QDir(path), options->platform, MatchDebugOrRelease, QString());
            for (const QString &library : libraries)
                options->binaries.append(path + QLatin1Char('/') + library);
        } else {
            options->binaries.append(path);
        }
    }
    options->translationsDirectory = options->directory + QLatin1String("/translations");
    return 0;
}

// Simple line wrapping at 80 character boundaries.
static inline QString lineBreak(QString s)
{
    for (int i = 80; i < s.size(); i += 80) {
        const int lastBlank = s.lastIndexOf(QLatin1Char(' '), i);
        if (lastBlank >= 0) {
            s[lastBlank] = QLatin1Char('\n');
            i = lastBlank + 1;
        }
    }
    return s;
}

static inline QString helpText(const QCommandLineParser &p)
{
    QString result = p.helpText();
    // Replace the default-generated text which is too long by a short summary
    // explaining how to enable single libraries.
    const int moduleStart = result.indexOf(QLatin1String("\n  --bluetooth"));
    const int argumentsStart = result.lastIndexOf(QLatin1String("\nArguments:"));
    if (moduleStart >= argumentsStart)
        return result;
    QString moduleHelp = QLatin1String(
        "\n\nQt libraries can be added by passing their name (-xml) or removed by passing\n"
        "the name prepended by --no- (--no-xml). Available libraries:\n");
    moduleHelp += lineBreak(QString::fromLatin1(formatQtModules(0xFFFFFFFFFFFFFFFFull, true)));
    moduleHelp += QLatin1Char('\n');
    result.replace(moduleStart, argumentsStart - moduleStart, moduleHelp);
    return result;
}

static inline bool isQtModule(const QString &libName)
{
    // Match Standard modules named Qt5XX.dll
    if (libName.size() < 3 || !libName.startsWith(QLatin1String("Qt"), Qt::CaseInsensitive))
        return false;
    const QChar version = libName.at(2);
    return version.isDigit() && (version.toLatin1() - '0') == QT_VERSION_MAJOR;
}

// Helper for recursively finding all dependent Qt libraries.
static bool findDependentQtLibraries(const QString &qtBinDir, const QString &binary, Platform platform,
                                     QString *errorMessage, QStringList *result,
                                     unsigned *wordSize = nullptr, bool *isDebug = nullptr,
                                     unsigned short *machineArch = nullptr,
                                     int *directDependencyCount = nullptr, int recursionDepth = 0)
{
    QStringList dependentLibs;
    if (directDependencyCount)
        *directDependencyCount = 0;
    if (!readExecutable(binary, platform, errorMessage, &dependentLibs, wordSize, isDebug, machineArch)) {
        errorMessage->prepend(QLatin1String("Unable to find dependent libraries of ") +
                              QDir::toNativeSeparators(binary) + QLatin1String(" :"));
        return false;
    }
    // Filter out the Qt libraries. Note that depends.exe finds libs from optDirectory if we
    // are run the 2nd time (updating). We want to check against the Qt bin dir libraries
    const int start = result->size();
    for (const QString &lib : qAsConst(dependentLibs)) {
        if (isQtModule(lib)) {
            const QString path = normalizeFileName(qtBinDir + QLatin1Char('/') + QFileInfo(lib).fileName());
            if (!result->contains(path))
                result->append(path);
        }
    }
    const int end = result->size();
    if (directDependencyCount)
        *directDependencyCount = end - start;
    // Recurse
    for (int i = start; i < end; ++i)
        if (!findDependentQtLibraries(qtBinDir, result->at(i), platform, errorMessage, result,
                                      nullptr, nullptr, nullptr, nullptr, recursionDepth + 1))
            return false;
    return true;
}

// Base class to filter debug/release Windows DLLs for functions to be passed to updateFile().
// Tries to pre-filter by namefilter and does check via PE.
class DllDirectoryFileEntryFunction {
public:
    explicit DllDirectoryFileEntryFunction(Platform platform,
                                           DebugMatchMode debugMatchMode, const QString &prefix = QString()) :
        m_platform(platform), m_debugMatchMode(debugMatchMode), m_prefix(prefix) {}

    QStringList operator()(const QDir &dir) const
        { return findSharedLibraries(dir, m_platform, m_debugMatchMode, m_prefix); }

private:
    const Platform m_platform;
    const DebugMatchMode m_debugMatchMode;
    const QString m_prefix;
};

static QString pdbFileName(QString libraryFileName)
{
    const int lastDot = libraryFileName.lastIndexOf(QLatin1Char('.')) + 1;
    if (lastDot <= 0)
        return QString();
    libraryFileName.replace(lastDot, libraryFileName.size() - lastDot, QLatin1String("pdb"));
    return libraryFileName;
}
static inline QStringList qmlCacheFileFilters()
{
    return QStringList() << QStringLiteral("*.jsc") << QStringLiteral("*.qmlc");
}

// File entry filter function for updateFile() that returns a list of files for
// QML import trees: DLLs (matching debgug) and .qml/,js, etc.
class QmlDirectoryFileEntryFunction {
public:
    enum Flags {
        DeployPdb = 0x1,
        SkipSources = 0x2
    };

    explicit QmlDirectoryFileEntryFunction(Platform platform, DebugMatchMode debugMatchMode, unsigned flags)
        : m_flags(flags), m_qmlNameFilter(QmlDirectoryFileEntryFunction::qmlNameFilters(flags))
        , m_dllFilter(platform, debugMatchMode)
    {}

    QStringList operator()(const QDir &dir) const
    {
        QStringList result;
        const QStringList &libraries = m_dllFilter(dir);
        for (const QString &library : libraries) {
            result.append(library);
            if (m_flags & DeployPdb) {
                const QString pdb = pdbFileName(library);
                if (QFileInfo(dir.absoluteFilePath(pdb)).isFile())
                    result.append(pdb);
            }
        }
        result.append(m_qmlNameFilter(dir));
        return result;
    }

private:
    static inline QStringList qmlNameFilters(unsigned flags)
    {
        QStringList result;
        result << QStringLiteral("qmldir") << QStringLiteral("*.qmltypes")
           << QStringLiteral("*.frag") << QStringLiteral("*.vert") // Shaders
           << QStringLiteral("*.ttf");
        if (!(flags & SkipSources)) {
            result << QStringLiteral("*.js") << QStringLiteral("*.qml") << QStringLiteral("*.png");
            result.append(qmlCacheFileFilters());
        }
        return result;
    }

    const unsigned m_flags;
    NameFilterFileEntryFunction m_qmlNameFilter;
    DllDirectoryFileEntryFunction m_dllFilter;
};

struct PluginModuleMapping
{
    const char *directoryName;
    quint64 module;
};

static const PluginModuleMapping pluginModuleMappings[] =
{
    {"qml1tooling", QtDeclarativeModule},
    {"gamepads", QtGamePadModule},
    {"accessible", QtGuiModule},
    {"iconengines", QtGuiModule},
    {"imageformats", QtGuiModule},
    {"platforms", QtGuiModule},
    {"platforminputcontexts", QtGuiModule},
    {"virtualkeyboard", QtGuiModule},
    {"geoservices", QtLocationModule},
    {"audio", QtMultimediaModule},
    {"mediaservice", QtMultimediaModule},
    {"playlistformats", QtMultimediaModule},
    {"bearer", QtNetworkModule},
    {"position", QtPositioningModule},
    {"printsupport", QtPrintSupportModule},
    {"scenegraph", QtQuickModule},
    {"qmltooling", QtQuickModule | QtQmlToolingModule},
    {"sensors", QtSensorsModule},
    {"sensorgestures", QtSensorsModule},
    {"canbus", QtSerialBusModule},
    {"sqldrivers", QtSqlModule},
    {"texttospeech", QtTextToSpeechModule},
    {"qtwebengine", QtWebEngineModule | QtWebEngineCoreModule | QtWebEngineWidgetsModule},
    {"styles", QtWidgetsModule},
    {"sceneparsers", Qt3DRendererModule},
    {"renderers", Qt3DRendererModule},
    {"renderplugins", Qt3DRendererModule},
    {"geometryloaders", Qt3DRendererModule},
    {"webview", QtWebViewModule}
};

static inline quint64 qtModuleForPlugin(const QString &subDirName)
{
    const auto end = std::end(pluginModuleMappings);
    const auto result =
        std::find_if(std::begin(pluginModuleMappings), end,
                     [&subDirName] (const PluginModuleMapping &m) { return subDirName == QLatin1String(m.directoryName); });
    return result != end ? result->module : 0; // "designer"
}

static quint64 qtModule(QString module, const QString &infix)
{
    // Match needle 'path/Qt5Core<infix><d>.dll' or 'path/libQt5Core<infix>.so.5.0'
    const int lastSlashPos = module.lastIndexOf(QLatin1Char('/'));
    if (lastSlashPos > 0)
        module.remove(0, lastSlashPos + 1);
    if (module.startsWith(QLatin1String("lib")))
        module.remove(0, 3);
    int endPos = infix.isEmpty() ? -1 : module.lastIndexOf(infix);
    if (endPos == -1)
        endPos = module.indexOf(QLatin1Char('.')); // strip suffixes '.so.5.0'.
    if (endPos > 0)
        module.truncate(endPos);
    // That should leave us with 'Qt5Core<d>'.
    for (const auto &qtModule : qtModuleEntries) {
        const QLatin1String libraryName(qtModule.libraryName);
        if (module == libraryName
            || (module.size() == libraryName.size() + 1 && module.startsWith(libraryName))) {
            return qtModule.module;
        }
    }
    return 0;
}

QStringList findQtPlugins(quint64 *usedQtModules, quint64 disabledQtModules,
                          unsigned disabledPlugins,
                          const QString &qtPluginsDirName, const QString &libraryLocation,
                          const QString &infix,
                          DebugMatchMode debugMatchModeIn, Platform platform, QString *platformPlugin)
{
    QString errorMessage;
    if (qtPluginsDirName.isEmpty())
        return QStringList();
    QDir pluginsDir(qtPluginsDirName);
    QStringList result;
    const QFileInfoList &pluginDirs = pluginsDir.entryInfoList(QStringList(QLatin1String("*")), QDir::Dirs | QDir::NoDotAndDotDot);
    for (const QFileInfo &subDirFi : pluginDirs) {
        const QString subDirName = subDirFi.fileName();
        const quint64 module = qtModuleForPlugin(subDirName);
        if (module & *usedQtModules) {
            const DebugMatchMode debugMatchMode = (module & QtWebEngineCoreModule)
                ? MatchDebugOrRelease // QTBUG-44331: Debug detection does not work for webengine, deploy all.
                : debugMatchModeIn;
            QDir subDir(subDirFi.absoluteFilePath());
            // Filter out disabled plugins
            if ((disabledPlugins & QtVirtualKeyboardPlugin) && subDirName == QLatin1String("virtualkeyboard"))
                continue;
            if (disabledQtModules & QtQmlToolingModule && subDirName == QLatin1String("qmltooling"))
                continue;
            // Filter for platform or any.
            QString filter;
            const bool isPlatformPlugin = subDirName == QLatin1String("platforms");
            if (isPlatformPlugin) {
                switch (platform) {
                case WindowsDesktopMsvc:
                case WindowsDesktopMinGW:
                    filter = QStringLiteral("qwindows");
                    break;
                case WinRtIntelMsvc:
                case WinRtArmMsvc:
                    filter = QStringLiteral("qwinrt");
                    break;
                case Unix:
                    filter = QStringLiteral("libqxcb");
                    break;
                case UnknownPlatform:
                    break;
                }
            } else {
                filter  = QLatin1String("*");
            }
            const QStringList plugins = findSharedLibraries(subDir, platform, debugMatchMode, filter);
            for (const QString &plugin : plugins) {
                // Filter out disabled plugins
                if ((disabledPlugins & QtVirtualKeyboardPlugin)
                    && plugin.startsWith(QLatin1String("qtvirtualkeyboardplugin"))) {
                    continue;
                }
                const QString pluginPath = subDir.absoluteFilePath(plugin);
                if (isPlatformPlugin)
                    *platformPlugin = pluginPath;
                QStringList dependentQtLibs;
                quint64 neededModules = 0;
                if (findDependentQtLibraries(libraryLocation, pluginPath, platform, &errorMessage, &dependentQtLibs)) {
                    for (int d = 0; d < dependentQtLibs.size(); ++ d)
                        neededModules |= qtModule(dependentQtLibs.at(d), infix);
                } else {
                    std::wcerr << "Warning: Cannot determine dependencies of "
                        << QDir::toNativeSeparators(pluginPath) << ": " << errorMessage << '\n';
                }
                if (const quint64 missingModules = neededModules & disabledQtModules) {
                    if (optVerboseLevel) {
                        std::wcout << "Skipping plugin " << plugin
                            << " due to disabled dependencies ("
                            << formatQtModules(missingModules).constData() << ").\n";
                    }
                } else {
                    if (const quint64 missingModules = (neededModules & ~*usedQtModules)) {
                        *usedQtModules |= missingModules;
                        if (optVerboseLevel)
                            std::wcout << "Adding " << formatQtModules(missingModules).constData() << " for " << plugin << '\n';
                    }
                    result.append(pluginPath);
                }
            } // for filter
        } // type matches
    } // for plugin folder
    return result;
}

static QStringList translationNameFilters(quint64 modules, const QString &prefix)
{
    QStringList result;
    for (const auto &qtModule : qtModuleEntries) {
        if ((qtModule.module & modules) && qtModule.translation) {
            const QString name = QLatin1String(qtModule.translation) +
                                 QLatin1Char('_') +  prefix + QStringLiteral(".qm");
            if (!result.contains(name))
                result.push_back(name);
        }
    }
    return result;
}

static bool deployTranslations(const QString &sourcePath, quint64 usedQtModules,
                               const QString &target, const Options &options,
                               QString *errorMessage)
{
    // Find available languages prefixes by checking on qtbase.
    QStringList prefixes;
    QDir sourceDir(sourcePath);
    const QStringList qmFilter = QStringList(QStringLiteral("qtbase_*.qm"));
    const QFileInfoList &qmFiles = sourceDir.entryInfoList(qmFilter);
    for (const QFileInfo &qmFi : qmFiles) {
        const QString prefix = qmFi.baseName().mid(7);
        if (options.languages.isEmpty() || options.languages.contains(prefix))
            prefixes.append(prefix);
    }
    if (prefixes.isEmpty()) {
        std::wcerr << "Warning: Could not find any translations in "
                   << QDir::toNativeSeparators(sourcePath) << " (developer build?)\n.";
        return true;
    }
    // Run lconvert to concatenate all files into a single named "qt_<prefix>.qm" in the application folder
    // Use QT_INSTALL_TRANSLATIONS as working directory to keep the command line short.
    const QString absoluteTarget = QFileInfo(target).absoluteFilePath();
    const QString binary = QStringLiteral("lconvert");
    QStringList arguments;
    for (const QString &prefix : qAsConst(prefixes)) {
        arguments.clear();
        const QString targetFile = QStringLiteral("qt_") + prefix + QStringLiteral(".qm");
        arguments.append(QStringLiteral("-o"));
        const QString targetFilePath = absoluteTarget + QLatin1Char('/') + targetFile;
        if (options.json)
            options.json->addFile(sourcePath +  QLatin1Char('/') + targetFile, absoluteTarget);
        arguments.append(QDir::toNativeSeparators(targetFilePath));
        const QFileInfoList &langQmFiles = sourceDir.entryInfoList(translationNameFilters(usedQtModules, prefix));
        for (const QFileInfo &langQmFileFi : langQmFiles) {
            // winrt relies on a proper list of deployed files. We cannot cheat an mention files we do not ship here.
            if (options.json && !options.isWinRt()) {
                options.json->addFile(langQmFileFi.absoluteFilePath(),
                                      absoluteTarget);
            }
            arguments.append(langQmFileFi.fileName());
        }
        if (optVerboseLevel)
            std::wcout << "Creating " << targetFile << "...\n";
        unsigned long exitCode;
        if ((options.updateFileFlags & SkipUpdateFile) == 0
            && (!runProcess(binary, arguments, sourcePath, &exitCode, nullptr, nullptr, errorMessage)
                || exitCode)) {
            return false;
        }
    } // for prefixes.
    return true;
}

struct DeployResult
{
    operator bool() const { return success; }

    bool success = false;
    bool isDebug = false;
    quint64 directlyUsedQtLibraries = 0;
    quint64 usedQtLibraries = 0;
    quint64 deployedQtLibraries = 0;
};

static QString libraryPath(const QString &libraryLocation, const char *name,
                           const QString &qtLibInfix, Platform platform, bool debug)
{
    QString result = libraryLocation + QLatin1Char('/');
    if (platform & WindowsBased) {
        result += QLatin1String(name);
        result += qtLibInfix;
        if (debug && platformHasDebugSuffix(platform))
            result += QLatin1Char('d');
    } else if (platform.testFlag(UnixBased)) {
        result += QStringLiteral("lib");
        result += QLatin1String(name);
        result += qtLibInfix;
    }
    result += sharedLibrarySuffix(platform);
    return result;
}

static QString vcDebugRedistDir() { return QStringLiteral("Debug_NonRedist"); }

static QString vcRedistDir()
{
    const char vcDirVar[] = "VCINSTALLDIR";
    const QChar slash(QLatin1Char('/'));
    QString vcRedistDirName = QDir::cleanPath(QFile::decodeName(qgetenv(vcDirVar)));
    if (vcRedistDirName.isEmpty()) {
        std::wcerr << "Warning: Cannot find Visual Studio installation directory, " << vcDirVar
            << " is not set.\n";
        return QString();
    }
    if (!vcRedistDirName.endsWith(slash))
        vcRedistDirName.append(slash);
    vcRedistDirName.append(QStringLiteral("redist"));
    if (!QFileInfo(vcRedistDirName).isDir()) {
        std::wcerr << "Warning: Cannot find Visual Studio redist directory, "
            << QDir::toNativeSeparators(vcRedistDirName).toStdWString() << ".\n";
        return QString();
    }
    const QString vc2017RedistDirName = vcRedistDirName + QStringLiteral("/MSVC");
    if (!QFileInfo(vc2017RedistDirName).isDir())
        return vcRedistDirName; // pre 2017
    // Look in reverse order for folder containing the debug redist folder
    const QFileInfoList subDirs =
        QDir(vc2017RedistDirName).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
    const bool isWindows10 = QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10;
    for (const QFileInfo &f : subDirs) {
        QString path = f.absoluteFilePath();
        if (QFileInfo(path + slash + vcDebugRedistDir()).isDir())
            return path;
        if (isWindows10) {
            path += QStringLiteral("/onecore");
            if (QFileInfo(path + slash + vcDebugRedistDir()).isDir())
                return path;
        }
    }
    std::wcerr << "Warning: Cannot find Visual Studio redist directory under "
        << QDir::toNativeSeparators(vc2017RedistDirName).toStdWString() << ".\n";
    return QString();
}

static QStringList compilerRunTimeLibs(Platform platform, bool isDebug, unsigned short machineArch)
{
    QStringList result;
    switch (platform) {
    case WindowsDesktopMinGW: { // MinGW: Add runtime libraries
        static const char *minGwRuntimes[] = {"*gcc_", "*stdc++", "*winpthread"};
        const QString gcc = findInPath(QStringLiteral("g++.exe"));
        if (gcc.isEmpty()) {
            std::wcerr << "Warning: Cannot find GCC installation directory. g++.exe must be in the path.\n";
            break;
        }
        const QString binPath = QFileInfo(gcc).absolutePath();
        QStringList filters;
        const QString suffix = QLatin1Char('*') + sharedLibrarySuffix(platform);
        for (auto minGwRuntime : minGwRuntimes)
            filters.append(QLatin1String(minGwRuntime) + suffix);
        const QFileInfoList &dlls = QDir(binPath).entryInfoList(filters, QDir::Files);
        for (const QFileInfo &dllFi : dlls)
                result.append(dllFi.absoluteFilePath());
    }
        break;
#ifdef Q_OS_WIN
    case WindowsDesktopMsvc: { // MSVC/Desktop: Add redistributable packages.
        QString vcRedistDirName = vcRedistDir();
        if (vcRedistDirName.isEmpty())
             break;
        QStringList redistFiles;
        QDir vcRedistDir(vcRedistDirName);
        const QString machineArchString = getArchString(machineArch);
        if (isDebug) {
            // Append DLLs from Debug_NonRedist\x??\Microsoft.VC<version>.DebugCRT.
            if (vcRedistDir.cd(vcDebugRedistDir()) && vcRedistDir.cd(machineArchString)) {
                const QStringList names = vcRedistDir.entryList(QStringList(QStringLiteral("Microsoft.VC*.DebugCRT")), QDir::Dirs);
                if (!names.isEmpty() && vcRedistDir.cd(names.first())) {
                    const QFileInfoList &dlls = vcRedistDir.entryInfoList(QStringList(QLatin1String("*.dll")));
                    for (const QFileInfo &dll : dlls)
                        redistFiles.append(dll.absoluteFilePath());
                }
            }
        } else { // release: Bundle vcredist<>.exe
            QString releaseRedistDir = vcRedistDirName;
            const QStringList countryCodes = vcRedistDir.entryList(QStringList(QStringLiteral("[0-9]*")), QDir::Dirs);
            if (!countryCodes.isEmpty()) // Pre MSVC2017
                releaseRedistDir += QLatin1Char('/') + countryCodes.constFirst();
            QFileInfo fi(releaseRedistDir + QLatin1Char('/') + QStringLiteral("vc_redist.")
                         + machineArchString + QStringLiteral(".exe"));
            if (!fi.isFile()) { // Pre MSVC2017/15.5
                fi.setFile(releaseRedistDir + QLatin1Char('/') + QStringLiteral("vcredist_")
                           + machineArchString + QStringLiteral(".exe"));
            }
            if (fi.isFile())
                redistFiles.append(fi.absoluteFilePath());
        }
        if (redistFiles.isEmpty()) {
            std::wcerr << "Warning: Cannot find Visual Studio " << (isDebug ? "debug" : "release")
                       << " redistributable files in " << QDir::toNativeSeparators(vcRedistDirName).toStdWString() << ".\n";
            break;
        }
        result.append(redistFiles);
    }
        break;
#endif // Q_OS_WIN
    default:
        break;
    }
    return result;
}

static inline int qtVersion(const QMap<QString, QString> &qmakeVariables)
{
    const QString versionString = qmakeVariables.value(QStringLiteral("QT_VERSION"));
    const QChar dot = QLatin1Char('.');
    const int majorVersion = versionString.section(dot, 0, 0).toInt();
    const int minorVersion = versionString.section(dot, 1, 1).toInt();
    const int patchVersion = versionString.section(dot, 2, 2).toInt();
    return (majorVersion << 16) | (minorVersion << 8) | patchVersion;
}

// Determine the Qt lib infix from the library path of "Qt5Core<qtblibinfix>[d].dll".
static inline QString qtlibInfixFromCoreLibName(const QString &path, bool isDebug, Platform platform)
{
    const int startPos = path.lastIndexOf(QLatin1Char('/')) + 8;
    int endPos = path.lastIndexOf(QLatin1Char('.'));
    if (isDebug && (platform & WindowsBased))
        endPos--;
    return endPos > startPos ? path.mid(startPos, endPos - startPos) : QString();
}

// Deploy a library along with its .pdb debug info file (MSVC) should it exist.
static bool updateLibrary(const QString &sourceFileName, const QString &targetDirectory,
                          const Options &options, QString *errorMessage)
{
    if (!updateFile(sourceFileName, targetDirectory, options.updateFileFlags, options.json, errorMessage)) {
        if (options.ignoreLibraryErrors) {
            std::wcerr << "Warning: Could not update " << sourceFileName << " :" << *errorMessage << '\n';
            errorMessage->clear();
            return true;
        }
        return false;
    }

    if (options.deployPdb) {
        const QFileInfo pdb(pdbFileName(sourceFileName));
        if (pdb.isFile())
            return updateFile(pdb.absoluteFilePath(), targetDirectory, options.updateFileFlags, nullptr, errorMessage);
    }
    return true;
}

static DeployResult deploy(const Options &options,
                           const QMap<QString, QString> &qmakeVariables,
                           QString *errorMessage)
{
    DeployResult result;

    const QChar slash = QLatin1Char('/');

    const QString qtBinDir = qmakeVariables.value(QStringLiteral("QT_INSTALL_BINS"));
    const QString libraryLocation = options.platform == Unix ? qmakeVariables.value(QStringLiteral("QT_INSTALL_LIBS")) : qtBinDir;
    const QString infix = qmakeVariables.value(QLatin1String(qmakeInfixKey));
    const int version = qtVersion(qmakeVariables);
    Q_UNUSED(version);

    if (optVerboseLevel > 1)
        std::wcout << "Qt binaries in " << QDir::toNativeSeparators(qtBinDir) << '\n';

    QStringList dependentQtLibs;
    bool detectedDebug;
    unsigned wordSize;
    unsigned short machineArch;
    int directDependencyCount = 0;
    if (!findDependentQtLibraries(libraryLocation, options.binaries.first(), options.platform, errorMessage, &dependentQtLibs, &wordSize,
                                  &detectedDebug, &machineArch, &directDependencyCount)) {
        return result;
    }
    for (int b = 1; b < options.binaries.size(); ++b) {
        if (!findDependentQtLibraries(libraryLocation, options.binaries.at(b), options.platform, errorMessage, &dependentQtLibs,
                                      nullptr, nullptr, nullptr)) {
            return result;
        }
    }

    DebugMatchMode debugMatchMode = MatchDebugOrRelease;
    result.isDebug = false;
    switch (options.debugDetection) {
    case Options::DebugDetectionAuto:
        // Debug detection is only relevant for Msvc/ClangMsvc which have distinct
        // runtimes and binaries. For anything else, use MatchDebugOrRelease
        // since also debug cannot be reliably detect for MinGW.
        if (options.platform.testFlag(Msvc) || options.platform.testFlag(ClangMsvc)) {
            result.isDebug = detectedDebug;
            debugMatchMode = result.isDebug ? MatchDebug : MatchRelease;
        }
        break;
    case Options::DebugDetectionForceDebug:
        result.isDebug = true;
        debugMatchMode = MatchDebug;
        break;
    case Options::DebugDetectionForceRelease:
        debugMatchMode = MatchRelease;
        break;
    }

    // Determine application type, check Quick2 is used by looking at the
    // direct dependencies (do not be fooled by QtWebKit depending on it).
    QString qtLibInfix;
    for (int m = 0; m < directDependencyCount; ++m) {
        const quint64 module = qtModule(dependentQtLibs.at(m), infix);
        result.directlyUsedQtLibraries |= module;
        if (module == QtCoreModule)
            qtLibInfix = qtlibInfixFromCoreLibName(dependentQtLibs.at(m), detectedDebug, options.platform);
    }

    const bool usesQml2 = !(options.disabledLibraries & QtQmlModule)
        && ((result.directlyUsedQtLibraries & (QtQmlModule | QtQuickModule | Qt3DQuickModule))
                                || (options.additionalLibraries & QtQmlModule));

    if (optVerboseLevel) {
        std::wcout << QDir::toNativeSeparators(options.binaries.first()) << ' '
                   << wordSize << " bit, " << (result.isDebug ? "debug" : "release")
                   << " executable";
        if (usesQml2)
            std::wcout << " [QML]";
        std::wcout << '\n';
    }

    if (dependentQtLibs.isEmpty()) {
        *errorMessage = QDir::toNativeSeparators(options.binaries.first()) +  QStringLiteral(" does not seem to be a Qt executable.");
        return result;
    }

    // Some Windows-specific checks: Qt5Core depends on ICU when configured with "-icu". Other than
    // that, Qt5WebKit has a hard dependency on ICU.
    if (options.platform.testFlag(WindowsBased))  {
        const QStringList qtLibs = dependentQtLibs.filter(QStringLiteral("Qt5Core"), Qt::CaseInsensitive)
            + dependentQtLibs.filter(QStringLiteral("Qt5WebKit"), Qt::CaseInsensitive);
        for (const QString &qtLib : qtLibs) {
            QStringList icuLibs = findDependentLibraries(qtLib, options.platform, errorMessage).filter(QStringLiteral("ICU"), Qt::CaseInsensitive);
            if (!icuLibs.isEmpty()) {
                // Find out the ICU version to add the data library icudtXX.dll, which does not show
                // as a dependency.
                QRegExp numberExpression(QStringLiteral("\\d+"));
                Q_ASSERT(numberExpression.isValid());
                const int index = numberExpression.indexIn(icuLibs.front());
                if (index >= 0)  {
                    const QString icuVersion = icuLibs.front().mid(index, numberExpression.matchedLength());
                    if (optVerboseLevel > 1)
                        std::wcout << "Adding ICU version " << icuVersion << '\n';
                    icuLibs.push_back(QStringLiteral("icudt") + icuVersion + QLatin1String(windowsSharedLibrarySuffix));
                }
                for (const QString &icuLib : qAsConst(icuLibs)) {
                    const QString icuPath = findInPath(icuLib);
                    if (icuPath.isEmpty()) {
                        *errorMessage = QStringLiteral("Unable to locate ICU library ") + icuLib;
                        return result;
                    }
                    dependentQtLibs.push_back(icuPath);
                } // for each icuLib
                break;
            } // !icuLibs.isEmpty()
        } // Qt5Core/Qt5WebKit
    } // Windows

    // Scan Quick2 imports
    QmlImportScanResult qmlScanResult;
    if (options.quickImports && usesQml2) {
        // Custom list of import paths provided by user
        QStringList qmlImportPaths = options.qmlImportPaths;
        // Qt's own QML modules
        qmlImportPaths << qmakeVariables.value(QStringLiteral("QT_INSTALL_QML"));
        QStringList qmlDirectories = options.qmlDirectories;
        if (qmlDirectories.isEmpty()) {
            const QString qmlDirectory = findQmlDirectory(options.platform, options.directory);
            if (!qmlDirectory.isEmpty())
                qmlDirectories.append(qmlDirectory);
        }
        for (const QString &qmlDirectory : qAsConst(qmlDirectories)) {
            if (optVerboseLevel >= 1)
                std::wcout << "Scanning " << QDir::toNativeSeparators(qmlDirectory) << ":\n";
            const QmlImportScanResult scanResult =
                runQmlImportScanner(qmlDirectory, qmlImportPaths,
                                    result.directlyUsedQtLibraries & QtWidgetsModule,
                                    options.platform, debugMatchMode, errorMessage);
            if (!scanResult.ok)
                return result;
            qmlScanResult.append(scanResult);
            // Additional dependencies of QML plugins.
            for (const QString &plugin : qAsConst(qmlScanResult.plugins)) {
                if (!findDependentQtLibraries(libraryLocation, plugin, options.platform, errorMessage, &dependentQtLibs, &wordSize, &detectedDebug, &machineArch))
                    return result;
            }
            if (optVerboseLevel >= 1) {
                std::wcout << "QML imports:\n";
                for (const QmlImportScanResult::Module &mod : qAsConst(qmlScanResult.modules)) {
                    std::wcout << "  '" << mod.name << "' "
                               << QDir::toNativeSeparators(mod.sourcePath) << '\n';
                }
                if (optVerboseLevel >= 2) {
                    std::wcout << "QML plugins:\n";
                    for (const QString &p : qAsConst(qmlScanResult.plugins))
                        std::wcout << "  " << QDir::toNativeSeparators(p) << '\n';
                }
            }
        }
    }

    // Find the plugins and check whether ANGLE, D3D are required on the platform plugin.
    QString platformPlugin;
    // Sort apart Qt 5 libraries in the ones that are represented by the
    // QtModule enumeration (and thus controlled by flags) and others.
    QStringList deployedQtLibraries;
    for (int i = 0 ; i < dependentQtLibs.size(); ++i)  {
        if (const quint64 qtm = qtModule(dependentQtLibs.at(i), infix))
            result.usedQtLibraries |= qtm;
        else
            deployedQtLibraries.push_back(dependentQtLibs.at(i)); // Not represented by flag.
    }
    result.deployedQtLibraries = (result.usedQtLibraries | options.additionalLibraries) & ~options.disabledLibraries;

    const QStringList plugins =
        findQtPlugins(&result.deployedQtLibraries,
                      // For non-QML applications, disable QML to prevent it from being pulled in by the qtaccessiblequick plugin.
                      options.disabledLibraries | (usesQml2 ? 0 : (QtQmlModule | QtQuickModule)),
                      options.disabledPlugins,
                      qmakeVariables.value(QStringLiteral("QT_INSTALL_PLUGINS")), libraryLocation, infix,
                      debugMatchMode, options.platform, &platformPlugin);

    // Apply options flags and re-add library names.
    QString qtGuiLibrary;
    for (const auto &qtModule : qtModuleEntries) {
        if (result.deployedQtLibraries & qtModule.module) {
            const QString library = libraryPath(libraryLocation, qtModule.libraryName, qtLibInfix, options.platform, result.isDebug);
            deployedQtLibraries.append(library);
            if (qtModule.module == QtGuiModule)
                qtGuiLibrary = library;
        }
    }

    if (optVerboseLevel >= 1) {
        std::wcout << "Direct dependencies: " << formatQtModules(result.directlyUsedQtLibraries).constData()
                   << "\nAll dependencies   : " << formatQtModules(result.usedQtLibraries).constData()
                   << "\nTo be deployed     : " << formatQtModules(result.deployedQtLibraries).constData() << '\n';
    }

    if (optVerboseLevel > 1)
        std::wcout << "Plugins: " << plugins.join(QLatin1Char(',')) << '\n';

    if ((result.deployedQtLibraries & QtGuiModule) && platformPlugin.isEmpty()) {
        *errorMessage =QStringLiteral("Unable to find the platform plugin.");
        return result;
    }

    // Check for ANGLE on the Qt5Gui library.
    if (options.platform.testFlag(WindowsBased) && !qtGuiLibrary.isEmpty())  {
        QString libGlesName = QStringLiteral("libGLESv2");
        if (result.isDebug && platformHasDebugSuffix(options.platform))
            libGlesName += QLatin1Char('d');
        libGlesName += QLatin1String(windowsSharedLibrarySuffix);
        QString libCombinedQtAngleName = QStringLiteral("QtANGLE");
        if (result.isDebug && platformHasDebugSuffix(options.platform))
            libCombinedQtAngleName += QLatin1Char('d');
        libCombinedQtAngleName += QLatin1String(windowsSharedLibrarySuffix);
        const QStringList guiLibraries = findDependentLibraries(qtGuiLibrary, options.platform, errorMessage);
        const bool dependsOnAngle = !guiLibraries.filter(libGlesName, Qt::CaseInsensitive).isEmpty();
        const bool dependsOnCombinedAngle = !guiLibraries.filter(libCombinedQtAngleName, Qt::CaseInsensitive).isEmpty();
        const bool dependsOnOpenGl = !guiLibraries.filter(QStringLiteral("opengl32"), Qt::CaseInsensitive).isEmpty();
        if (options.angleDetection != Options::AngleDetectionForceOff
            && (dependsOnAngle || dependsOnCombinedAngle || !dependsOnOpenGl || options.angleDetection == Options::AngleDetectionForceOn)) {
            const QString combinedAngleFullPath = qtBinDir + slash + libCombinedQtAngleName;
            if (QFileInfo::exists(combinedAngleFullPath)) {
                deployedQtLibraries.append(combinedAngleFullPath);
            } else {
                const QString libGlesFullPath = qtBinDir + slash + libGlesName;
                deployedQtLibraries.append(libGlesFullPath);
                QString libEglFullPath = qtBinDir + slash + QStringLiteral("libEGL");
                if (result.isDebug && platformHasDebugSuffix(options.platform))
                    libEglFullPath += QLatin1Char('d');
                libEglFullPath += QLatin1String(windowsSharedLibrarySuffix);
                deployedQtLibraries.append(libEglFullPath);
            }
            // Find the system D3d Compiler matching the D3D library.
            // Any arm64 OS will be new enough to be shipped with the D3DCompiler inbox.
            if (options.systemD3dCompiler && !options.isWinRt() && machineArch != IMAGE_FILE_MACHINE_ARM64) {
                const QString d3dCompiler = findD3dCompiler(options.platform, qtBinDir, wordSize);
                if (d3dCompiler.isEmpty()) {
                    std::wcerr << "Warning: Cannot find any version of the d3dcompiler DLL.\n";
                } else {
                    deployedQtLibraries.push_back(d3dCompiler);
                }
            }
        } // deployAngle
        if (options.softwareRasterizer && !dependsOnOpenGl) {
            const QFileInfo softwareRasterizer(qtBinDir + slash + QStringLiteral("opengl32sw") + QLatin1String(windowsSharedLibrarySuffix));
            if (softwareRasterizer.isFile())
                deployedQtLibraries.append(softwareRasterizer.absoluteFilePath());
        }
    } // Windows

    // We need to copy ucrtbased.dll on WinRT as this library is not part of
    // the c runtime package. VS 2015 does the same when deploying to a device
    // or creating an appx.
    if (result.isDebug && options.platform == WinRtArmMsvc
             && qmakeVariables.value(QStringLiteral("QMAKE_XSPEC")).endsWith(QLatin1String("msvc2015"))) {
        const QString extensionPath = QString::fromLocal8Bit(qgetenv("ExtensionSdkDir"));
        const QString ucrtVersion = QString::fromLocal8Bit(qgetenv("UCRTVersion"));
        if (extensionPath.isEmpty() || ucrtVersion.isEmpty()) {
            std::wcerr << "Warning: Cannot find ucrtbased.dll as either "
                << "ExtensionSdkDir or UCRTVersion is not set in "
                << "your environment.\n";
        } else {
            const QString ucrtbasedLib = extensionPath
                    + QStringLiteral("/Microsoft.UniversalCRT.Debug/")
                    + ucrtVersion
                    + QStringLiteral("/Redist/Debug/arm/ucrtbased.dll");
            const QFileInfo ucrtPath(ucrtbasedLib);
            if (ucrtPath.exists() && ucrtPath.isFile()) {
                deployedQtLibraries.append(ucrtPath.absoluteFilePath());
            } else {
                std::wcerr << "Warning: Cannot find ucrtbased.dll at "
                           << QDir::toNativeSeparators(ucrtbasedLib)
                           << " or it is not a file.\n";
            }
        }
    }

    // Update libraries
    if (options.libraries) {
        const QString targetPath = options.libraryDirectory.isEmpty() ?
            options.directory : options.libraryDirectory;
        QStringList libraries = deployedQtLibraries;
        if (options.compilerRunTime)
            libraries.append(compilerRunTimeLibs(options.platform, result.isDebug, machineArch));
        for (const QString &qtLib : qAsConst(libraries)) {
            if (!updateLibrary(qtLib, targetPath, options, errorMessage))
                return result;
        }

        if (options.patchQt  && !options.dryRun && !options.isWinRt()) {
            const QString qt5CoreName = QFileInfo(libraryPath(libraryLocation, "Qt5Core", qtLibInfix,
                                                              options.platform, result.isDebug)).fileName();
#ifndef QT_RELOCATABLE
            if (!patchQtCore(targetPath + QLatin1Char('/') + qt5CoreName, errorMessage)) {
                std::wcerr << "Warning: " << *errorMessage << '\n';
                errorMessage->clear();
            }
#endif
        }
    } // optLibraries

    // Update plugins
    if (options.plugins) {
        const QString targetPath = options.pluginDirectory.isEmpty() ?
            options.directory : options.pluginDirectory;
        QDir dir(targetPath);
        if (!dir.exists() && !dir.mkpath(QStringLiteral("."))) {
            *errorMessage = QLatin1String("Cannot create ") +
                            QDir::toNativeSeparators(dir.absolutePath()) +  QLatin1Char('.');
            return result;
        }
        for (const QString &plugin : plugins) {
            const QString targetDirName = plugin.section(slash, -2, -2);
            const QString targetPath = dir.absoluteFilePath(targetDirName);
            if (!dir.exists(targetDirName)) {
                if (optVerboseLevel)
                    std::wcout << "Creating directory " << targetPath << ".\n";
                if (!(options.updateFileFlags & SkipUpdateFile) && !dir.mkdir(targetDirName)) {
                    *errorMessage = QStringLiteral("Cannot create ") + targetDirName +  QLatin1Char('.');
                    return result;
                }
            }
            if (!updateLibrary(plugin, targetPath, options, errorMessage))
                return result;
        }
    } // optPlugins

    // Update Quick imports
    const bool usesQuick1 = result.deployedQtLibraries & QtDeclarativeModule;
    // Do not be fooled by QtWebKit.dll depending on Quick into always installing Quick imports
    // for WebKit1-applications. Check direct dependency only.
    if (options.quickImports && (usesQuick1 || usesQml2)) {
        if (usesQml2) {
            for (const QmlImportScanResult::Module &module : qAsConst(qmlScanResult.modules)) {
                const QString installPath = module.installPath(options.directory);
                if (optVerboseLevel > 1)
                    std::wcout << "Installing: '" << module.name
                               << "' from " << module.sourcePath << " to "
                               << QDir::toNativeSeparators(installPath) << '\n';
                if (installPath != options.directory && !createDirectory(installPath, errorMessage))
                    return result;
                unsigned updateFileFlags = options.updateFileFlags | SkipQmlDesignerSpecificsDirectories;
                unsigned qmlDirectoryFileFlags = 0;
                if (options.deployPdb)
                    qmlDirectoryFileFlags |= QmlDirectoryFileEntryFunction::DeployPdb;
                if (!updateFile(module.sourcePath, QmlDirectoryFileEntryFunction(options.platform, debugMatchMode, qmlDirectoryFileFlags),
                                installPath, updateFileFlags, options.json, errorMessage)) {
                    return result;
                }
            }
        } // Quick 2
        if (usesQuick1) {
            const QString quick1ImportPath = qmakeVariables.value(QStringLiteral("QT_INSTALL_IMPORTS"));
            const QmlDirectoryFileEntryFunction qmlFileEntryFunction(options.platform, debugMatchMode, options.deployPdb ? QmlDirectoryFileEntryFunction::DeployPdb : 0);
            QStringList quick1Imports(QStringLiteral("Qt"));
            if (result.deployedQtLibraries & QtWebKitModule)
                quick1Imports << QStringLiteral("QtWebKit");
            for (const QString &quick1Import : qAsConst(quick1Imports)) {
                const QString sourceFile = quick1ImportPath + slash + quick1Import;
                if (!updateFile(sourceFile, qmlFileEntryFunction, options.directory, options.updateFileFlags, options.json, errorMessage))
                    return result;
            }
        } // Quick 1
    } // optQuickImports

    if (options.translations) {
        if (!options.dryRun && !createDirectory(options.translationsDirectory, errorMessage))
            return result;
        if (!deployTranslations(qmakeVariables.value(QStringLiteral("QT_INSTALL_TRANSLATIONS")),
                                result.deployedQtLibraries, options.translationsDirectory,
                                options, errorMessage)) {
            return result;
        }
    }

    result.success = true;
    return result;
}

static bool deployWebProcess(const QMap<QString, QString> &qmakeVariables,
                             const char *binaryName,
                             const Options &sourceOptions, QString *errorMessage)
{
    // Copy the web process and its dependencies
    const QString webProcess = webProcessBinary(binaryName, sourceOptions.platform);
    const QString webProcessSource = qmakeVariables.value(QStringLiteral("QT_INSTALL_LIBEXECS")) +
                                     QLatin1Char('/') + webProcess;
    if (!updateFile(webProcessSource, sourceOptions.directory, sourceOptions.updateFileFlags, sourceOptions.json, errorMessage))
        return false;
    Options options(sourceOptions);
    options.binaries.append(options.directory + QLatin1Char('/') + webProcess);
    options.quickImports = false;
    options.translations = false;
    return deploy(options, qmakeVariables, errorMessage);
}

static bool deployWebEngineCore(const QMap<QString, QString> &qmakeVariables,
                                const Options &options, bool isDebug, QString *errorMessage)
{
    static const char *installDataFiles[] = {"icudtl.dat",
                                             "qtwebengine_devtools_resources.pak",
                                             "qtwebengine_resources.pak",
                                             "qtwebengine_resources_100p.pak",
                                             "qtwebengine_resources_200p.pak"};
    QByteArray webEngineProcessName(webEngineProcessC);
    if (isDebug && platformHasDebugSuffix(options.platform))
        webEngineProcessName.append('d');
    if (optVerboseLevel)
        std::wcout << "Deploying: " << webEngineProcessName.constData() << "...\n";
    if (!deployWebProcess(qmakeVariables, webEngineProcessName, options, errorMessage))
        return false;
    const QString resourcesSubDir = QStringLiteral("/resources");
    const QString resourcesSourceDir
        = qmakeVariables.value(QStringLiteral("QT_INSTALL_DATA")) + resourcesSubDir
            + QLatin1Char('/');
    const QString resourcesTargetDir(options.directory + resourcesSubDir);
    if (!createDirectory(resourcesTargetDir, errorMessage))
        return false;
    for (auto installDataFile : installDataFiles) {
        if (!updateFile(resourcesSourceDir + QLatin1String(installDataFile),
                        resourcesTargetDir, options.updateFileFlags, options.json, errorMessage)) {
            return false;
        }
    }
    const QFileInfo translations(qmakeVariables.value(QStringLiteral("QT_INSTALL_TRANSLATIONS"))
                                 + QStringLiteral("/qtwebengine_locales"));
    if (!translations.isDir()) {
        std::wcerr << "Warning: Cannot find the translation files of the QtWebEngine module at "
            << QDir::toNativeSeparators(translations.absoluteFilePath()) << ".\n";
        return true;
    }
    if (options.translations) {
        // Copy the whole translations directory.
        return createDirectory(options.translationsDirectory, errorMessage)
                && updateFile(translations.absoluteFilePath(), options.translationsDirectory,
                              options.updateFileFlags, options.json, errorMessage);
    }
    // Translations have been turned off, but QtWebEngine needs at least one.
    const QFileInfo enUSpak(translations.filePath() + QStringLiteral("/en-US.pak"));
    if (!enUSpak.exists()) {
        std::wcerr << "Warning: Cannot find "
                   << QDir::toNativeSeparators(enUSpak.absoluteFilePath()) << ".\n";
        return true;
    }
    const QString webEngineTranslationsDir = options.translationsDirectory + QLatin1Char('/')
            + translations.fileName();
    if (!createDirectory(webEngineTranslationsDir, errorMessage))
        return false;
    return updateFile(enUSpak.absoluteFilePath(), webEngineTranslationsDir,
                      options.updateFileFlags, options.json, errorMessage);
}

int main(int argc, char **argv)
{
    QCoreApplication a(argc, argv);
    QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));

    const QByteArray qtBinPath = QFile::encodeName(QDir::toNativeSeparators(QCoreApplication::applicationDirPath()));
    QByteArray path = qgetenv("PATH");
    if (!path.contains(qtBinPath)) { // QTBUG-39177, ensure Qt is in the path so that qt.conf is taken into account.
        path += ';';
        path += qtBinPath;
        qputenv("PATH", path);
    }

    Options options;
    QString errorMessage;
    const QMap<QString, QString> qmakeVariables = queryQMakeAll(&errorMessage);
    const QString xSpec = qmakeVariables.value(QStringLiteral("QMAKE_XSPEC"));
    options.platform = platformFromMkSpec(xSpec);
    if (options.platform == WindowsDesktopMinGW || options.platform == WindowsDesktopMsvc)
        options.compilerRunTime = true;

    {   // Command line
        QCommandLineParser parser;
        QString errorMessage;
        const int result = parseArguments(QCoreApplication::arguments(), &parser, &options, &errorMessage);
        if (result & CommandLineParseError)
            std::wcerr << errorMessage << "\n\n";
        if (result & CommandLineParseHelpRequested)
            std::fputs(qPrintable(helpText(parser)), stdout);
        if (result & CommandLineParseError)
            return 1;
        if (result & CommandLineParseHelpRequested)
            return 0;
    }

    if (qmakeVariables.isEmpty() || xSpec.isEmpty() || !qmakeVariables.contains(QStringLiteral("QT_INSTALL_BINS"))) {
        std::wcerr << "Unable to query qmake: " << errorMessage << '\n';
        return 1;
    }

    if (options.platform == UnknownPlatform) {
        std::wcerr << "Unsupported platform " << xSpec << '\n';
        return 1;
    }

    // Create directories
    if (!createDirectory(options.directory, &errorMessage)) {
        std::wcerr << errorMessage << '\n';
        return 1;
    }
    if (!options.libraryDirectory.isEmpty() && options.libraryDirectory != options.directory
        && !createDirectory(options.libraryDirectory, &errorMessage)) {
        std::wcerr << errorMessage << '\n';
        return 1;
    }

    if (optWebKit2 == OptionEnabled)
        options.additionalLibraries |= QtWebKitModule;


    const DeployResult result = deploy(options, qmakeVariables, &errorMessage);
    if (!result) {
        std::wcerr << errorMessage << '\n';
        return 1;
    }

    if ((optWebKit2 != OptionDisabled)
        && (optWebKit2 == OptionEnabled
            || ((result.deployedQtLibraries & QtWebKitModule)
                && (result.directlyUsedQtLibraries & QtQuickModule)))) {
        if (optVerboseLevel)
            std::wcout << "Deploying: " << webKitProcessC << "...\n";
        if (!deployWebProcess(qmakeVariables, webKitProcessC, options, &errorMessage)) {
            std::wcerr << errorMessage << '\n';
            return 1;
        }
    }

    if (result.deployedQtLibraries & QtWebEngineCoreModule) {
        if (!deployWebEngineCore(qmakeVariables, options, result.isDebug, &errorMessage)) {
            std::wcerr << errorMessage << '\n';
            return 1;
        }
    }

    if (options.json) {
        if (options.list)
            std::fputs(options.json->toList(options.list, options.directory).constData(), stdout);
        else
            std::fputs(options.json->toJson().constData(), stdout);
        delete options.json;
        options.json = nullptr;
    }

    return 0;
}

QT_END_NAMESPACE
