Использование windeployqt при сборке win-версии на lin-хосте
От: Conductor СССР  
Дата: 09.01.25 23:42
Оценка: 4 (1)
Может, кому пригодится.
Как известно, использовать windeployqt при сборке win-версии (mingw) на lin-хосте нельзя (с Qt6 не проверял, но с Qt5.15 так). Нельзя потому, что в qttools/src/shared/winutils/utils.cpp для !Q_OS_WIN:
bool readPeExecutable(const QString &, QString *errorMessage,
                      QStringList *, unsigned *, bool *, bool, unsigned short *)
{
    *errorMessage = QStringLiteral("Not implemented.");
    return false;
}

Однако, если реализовать функцию, например, так:
bool readPeExecutable(const QString &peExecutableFileName, QString *errorMessage,
                      QStringList *dependentLibraries, unsigned *wordSize,
                      bool *isDebug, bool isMinGW, unsigned short *machineArch)
{
    Q_UNUSED(isMinGW);

    if (!errorMessage)
    {
        assert(false && "errorMessage is nullptr");
        return false;
    }

    if (dependentLibraries)
    {
        dependentLibraries->clear();
    }

    if (isDebug)
    {
        // separate debug info
        *isDebug = false;
    }

    //////////////////////////////////////////////////////////////////////////
    // not used
    //////////////////////////////////////////////////////////////////////////
    if (wordSize)
    {
        *wordSize = 0;
    }

    if (machineArch)
    {
        *machineArch = 0;
    }
    //////////////////////////////////////////////////////////////////////////

    if (!QFileInfo::exists(peExecutableFileName))
    {
        *errorMessage = QString::fromLatin1("Cannot open '%1': file doesn't exist").arg(peExecutableFileName);
        return false;
    }

    if (!dependentLibraries)
    {
        // nothing to do
        return true;
    }

    auto exec = [](const char* cmd, bool &isError) -> QString
    {
        isError = false;

        std::array<char, 128> buffer;
        std::string result;
        std::unique_ptr<FILE, decltype(&::pclose)> pipe(::popen(cmd, "r"), ::pclose);
        if (!pipe)
        {
            isError = true;
            return QString{};
        }

        while (::fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
        {
            result += buffer.data();
        }

        isError = WEXITSTATUS(::pclose(pipe.release())) != 0;

        return QString::fromStdString(result);
    };

    bool isError;
    QString output = exec(qPrintable(QStringLiteral("peldd ") + peExecutableFileName), isError);

    if (!isError)
    {
        *dependentLibraries = output.split(QStringLiteral("\n"), Qt::SkipEmptyParts);
    }

    return !isError;
}

то работать будет.

Единственное условие: peldd (https://github.com/gsauthof/pe-util.git) должна быть в PATH.
Да, и ещё: при вызове windeployqt в PATH первой (или единственной) должна быть mingw-версия qmake, чтобы правильно определилась платформа.
Отредактировано 09.01.2025 23:52 Conductor . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.