2019-01-26 07:54:56 +03:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2018-2019 QuasarApp.
|
|
|
|
* Distributed under the lgplv3 software license, see the accompanying
|
|
|
|
* Everyone is permitted to copy and distribute verbatim copies
|
|
|
|
* of this license document, but changing it is not allowed.
|
|
|
|
*/
|
|
|
|
|
2018-11-15 18:00:23 +03:00
|
|
|
#include "windependenciesscanner.h"
|
2018-12-09 17:35:07 +03:00
|
|
|
#include "deployutils.h"
|
2018-11-15 18:00:23 +03:00
|
|
|
|
|
|
|
#include <QList>
|
2018-11-18 17:22:05 +03:00
|
|
|
#include <QDir>
|
2018-11-26 16:17:46 +03:00
|
|
|
#include <QDebug>
|
2018-11-15 18:00:23 +03:00
|
|
|
|
2018-12-09 17:35:07 +03:00
|
|
|
|
2018-12-01 21:04:52 +03:00
|
|
|
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;
|
|
|
|
AngleDetection angleDetection = AngleDetectionAuto;
|
|
|
|
bool softwareRasterizer = true;
|
|
|
|
Platform platform = Windows;
|
|
|
|
quint64 additionalLibraries = 0;
|
|
|
|
quint64 disabledLibraries = 0;
|
|
|
|
unsigned updateFileFlags = 0;
|
|
|
|
QStringList qmlDirectories; // Project's QML files.
|
|
|
|
QString directory;
|
|
|
|
QString translationsDirectory; // Translations target directory
|
|
|
|
QString libraryDirectory;
|
|
|
|
QString pluginDirectory;
|
|
|
|
QStringList binaries;
|
|
|
|
JsonOutput *json = nullptr;
|
|
|
|
ListOption list = ListNone;
|
|
|
|
DebugDetection debugDetection = DebugDetectionAuto;
|
|
|
|
bool deployPdb = false;
|
|
|
|
bool dryRun = false;
|
|
|
|
bool patchQt = true;
|
|
|
|
|
|
|
|
inline bool isWinRt() const {
|
|
|
|
return platform == WinRtArm || platform == WinRtIntel;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-11-15 18:00:23 +03:00
|
|
|
WinDependenciesScanner::WinDependenciesScanner() {}
|
|
|
|
|
2018-12-09 17:35:07 +03:00
|
|
|
QMap<QString, QString> WinDependenciesScanner::qMakeAll(QString *errorMessage, const QString& binary)
|
|
|
|
{
|
|
|
|
QByteArray stdOut;
|
|
|
|
QByteArray stdErr;
|
|
|
|
unsigned long exitCode = 0;
|
|
|
|
if (!runProcess(binary, QStringList(QStringLiteral("-query")), QString(), &exitCode, &stdOut, &stdErr, errorMessage))
|
|
|
|
return QMap<QString, QString>();
|
|
|
|
if (exitCode) {
|
|
|
|
*errorMessage = binary + QStringLiteral(" returns ") + QString::number(exitCode)
|
|
|
|
+ QStringLiteral(": ") + QString::fromLocal8Bit(stdErr);
|
|
|
|
return QMap<QString, QString>();
|
|
|
|
}
|
|
|
|
const QString output = QString::fromLocal8Bit(stdOut).trimmed().remove(QLatin1Char('\r'));
|
|
|
|
QMap<QString, QString> result;
|
|
|
|
const int size = output.size();
|
|
|
|
for (int pos = 0; pos < size; ) {
|
|
|
|
const int colonPos = output.indexOf(QLatin1Char(':'), pos);
|
|
|
|
if (colonPos < 0)
|
|
|
|
break;
|
|
|
|
int endPos = output.indexOf(QLatin1Char('\n'), colonPos + 1);
|
|
|
|
if (endPos < 0)
|
|
|
|
endPos = size;
|
|
|
|
const QString key = output.mid(pos, colonPos - pos);
|
|
|
|
const QString value = output.mid(colonPos + 1, endPos - colonPos - 1);
|
|
|
|
result.insert(key, value);
|
|
|
|
pos = endPos + 1;
|
|
|
|
}
|
|
|
|
QFile qconfigPriFile(result.value(QStringLiteral("QT_HOST_DATA")) + QStringLiteral("/mkspecs/qconfig.pri"));
|
|
|
|
if (qconfigPriFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
|
|
while (true) {
|
|
|
|
const QByteArray line = qconfigPriFile.readLine();
|
|
|
|
if (line.isEmpty())
|
|
|
|
break;
|
|
|
|
if (line.startsWith("QT_LIBINFIX")) {
|
|
|
|
const int pos = line.indexOf('=');
|
|
|
|
if (pos >= 0) {
|
|
|
|
const QString infix = QString::fromUtf8(line.right(line.size() - pos - 1).trimmed());
|
|
|
|
if (!infix.isEmpty())
|
|
|
|
result.insert(QLatin1String(qmakeInfixKey), infix);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
std::wcerr << "Warning: Unable to read " << QDir::toNativeSeparators(qconfigPriFile.fileName())
|
|
|
|
<< ": " << qconfigPriFile.errorString()<< '\n';
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-11-23 14:56:55 +03:00
|
|
|
void WinDependenciesScanner::setEnvironment(const QStringList &env) {
|
2018-11-18 17:22:05 +03:00
|
|
|
QDir dir;
|
2018-11-23 14:56:55 +03:00
|
|
|
for (auto i : env) {
|
2018-12-09 17:35:07 +03:00
|
|
|
|
2018-11-18 17:22:05 +03:00
|
|
|
dir.setPath(i);
|
|
|
|
if (!dir.exists()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-11-23 14:56:55 +03:00
|
|
|
auto list = dir.entryInfoList(QStringList() << "*.dll",
|
2018-11-18 17:22:05 +03:00
|
|
|
QDir::Files| QDir::NoDotAndDotDot);
|
|
|
|
|
2018-11-23 14:56:55 +03:00
|
|
|
for (auto i : list) {
|
2018-12-09 17:35:07 +03:00
|
|
|
|
|
|
|
auto newPriority = DeployUtils::getLibPriority(i.absoluteFilePath());
|
|
|
|
auto oldPriority = DeployUtils::getLibPriority(_EnvLibs.value(i.fileName(), ""));
|
|
|
|
|
|
|
|
if (newPriority > oldPriority)
|
|
|
|
_EnvLibs.insert(i.fileName(), i.absoluteFilePath());
|
2018-11-23 14:56:55 +03:00
|
|
|
}
|
2018-11-18 17:22:05 +03:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-11-26 16:17:46 +03:00
|
|
|
Platform WinDependenciesScanner::platformFromMkSpec(const QString &xSpec)
|
|
|
|
{
|
|
|
|
if (xSpec == QLatin1String("linux-g++"))
|
|
|
|
return Unix;
|
|
|
|
if (xSpec.startsWith(QLatin1String("win32-")))
|
|
|
|
return xSpec.contains(QLatin1String("g++")) ? WindowsMinGW : Windows;
|
|
|
|
if (xSpec.startsWith(QLatin1String("winrt-x")))
|
|
|
|
return WinRtIntel;
|
|
|
|
if (xSpec.startsWith(QLatin1String("winrt-arm")))
|
|
|
|
return WinRtArm;
|
|
|
|
if (xSpec.startsWith(QLatin1String("wince"))) {
|
|
|
|
if (xSpec.contains(QLatin1String("-x86-")))
|
|
|
|
return WinCEIntel;
|
|
|
|
if (xSpec.contains(QLatin1String("-arm")))
|
|
|
|
return WinCEArm;
|
|
|
|
}
|
|
|
|
return UnknownPlatform;
|
|
|
|
}
|
|
|
|
|
2018-12-09 17:35:07 +03:00
|
|
|
QStringList WinDependenciesScanner::scan(const QString &path, Platform platfr,
|
|
|
|
const QString& qmake) {
|
2018-11-18 17:22:05 +03:00
|
|
|
QStringList result;
|
|
|
|
|
2018-11-26 16:17:46 +03:00
|
|
|
QString errorMessage;
|
|
|
|
|
2018-12-01 21:04:52 +03:00
|
|
|
if (platfr == Platform::UnknownPlatform) {
|
|
|
|
|
2018-12-09 17:35:07 +03:00
|
|
|
const auto qmakeVariables = qMakeAll(&errorMessage, qmake);
|
2018-12-01 21:04:52 +03:00
|
|
|
const QString xSpec = qmakeVariables.value(QStringLiteral("QMAKE_XSPEC"));
|
|
|
|
platfr = platformFromMkSpec(xSpec);
|
|
|
|
}
|
|
|
|
|
2018-11-26 16:17:46 +03:00
|
|
|
QStringList dep;
|
2018-11-26 21:53:44 +03:00
|
|
|
readExecutable(path, platfr, &errorMessage, &dep);
|
2018-11-26 16:17:46 +03:00
|
|
|
|
|
|
|
if (!errorMessage.isEmpty()) {
|
|
|
|
qCritical() << errorMessage;
|
|
|
|
return result;
|
|
|
|
}
|
2018-11-18 17:22:05 +03:00
|
|
|
|
2018-11-23 14:56:55 +03:00
|
|
|
for (auto i : dep) {
|
|
|
|
QString lib(i);
|
|
|
|
if (_EnvLibs.count(lib)) {
|
|
|
|
result.push_back(_EnvLibs.value(lib));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-18 17:22:05 +03:00
|
|
|
return result;
|
2018-11-15 18:00:23 +03:00
|
|
|
}
|
2018-11-23 14:56:55 +03:00
|
|
|
|
|
|
|
WinDependenciesScanner::~WinDependenciesScanner() {
|
|
|
|
|
|
|
|
}
|