summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-12-23 15:37:49 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-12-23 15:37:49 +0100
commitf3d5a7307bb232218c098b6c44defab5f182d647 (patch)
treed0c87cd16bca80dad42f6ef46271bb4a9bdc2546 /src
parent9a816664b1eafdce52fab9e2d5ec535fc28a782c (diff)
parent856ba53f77bc3d7b39c5e35d0249ead595dc0439 (diff)
Merge remote-tracking branch 'origin/stable' into dev
Diffstat (limited to 'src')
-rw-r--r--src/androiddeployqt/main.cpp168
-rw-r--r--src/designer/src/components/formeditor/formwindow.cpp1
-rw-r--r--src/designer/src/components/formeditor/qdesignerundostack.cpp6
-rw-r--r--src/designer/src/components/formeditor/qdesignerundostack.h1
-rw-r--r--src/macdeployqt/macchangeqt/main.cpp2
-rw-r--r--src/qdbus/qdbus/qdbus.cpp12
-rw-r--r--src/windeployqt/main.cpp58
-rw-r--r--src/windeployqt/qmlutils.cpp58
-rw-r--r--src/windeployqt/qmlutils.h11
-rw-r--r--src/windeployqt/utils.cpp8
10 files changed, 250 insertions, 75 deletions
diff --git a/src/androiddeployqt/main.cpp b/src/androiddeployqt/main.cpp
index 9d3cf507b..9c4071547 100644
--- a/src/androiddeployqt/main.cpp
+++ b/src/androiddeployqt/main.cpp
@@ -51,6 +51,7 @@
#include <QDateTime>
#include <QStandardPaths>
#include <QUuid>
+#include <QDirIterator>
#include <algorithm>
static const bool mustReadOutputAnyway = true; // pclose seems to return the wrong error code unless we read the output
@@ -77,6 +78,7 @@ struct Options
Options()
: helpRequested(false)
, verbose(false)
+ , timing(false)
, minimumAndroidVersion(9)
, targetAndroidVersion(10)
, deploymentMechanism(Bundled)
@@ -105,6 +107,8 @@ struct Options
bool helpRequested;
bool verbose;
+ bool timing;
+ QTime timer;
// External tools
QString sdkPath;
@@ -164,7 +168,7 @@ struct Options
QStringList initClasses;
QString temporaryDirectoryName;
bool fetchedRemoteModificationDates;
- QHash<QString, QDateTime> remoteModificationDates;
+ QDateTime remoteModificationDate;
QStringList permissions;
QStringList features;
};
@@ -302,6 +306,8 @@ Options parseOptions()
if (options.inputFileName.isEmpty())
options.inputFileName = QString::fromLatin1("android-lib%1.so-deployment-settings.json").arg(QDir::current().dirName());
+ options.timing = qEnvironmentVariableIsSet("ANDROIDDEPLOYQT_TIMING_OUTPUT");
+
return options;
}
@@ -1389,11 +1395,9 @@ bool fetchRemoteModifications(Options *options, const QString &directory)
options->fetchedRemoteModificationDates = true;
FILE *adbCommand = runAdb(*options, QLatin1String(" ls ") + directory);
- QHash<QString, QDateTime> ret;
if (adbCommand == 0)
return false;
- QStringList possibleDirectoriesToTry;
char buffer[512];
while (fgets(buffer, sizeof(buffer), adbCommand) != 0) {
QByteArray line = QByteArray::fromRawData(buffer, qstrlen(buffer));
@@ -1405,24 +1409,27 @@ bool fetchRemoteModifications(Options *options, const QString &directory)
|| line.at(26) != ' ') {
continue;
}
+ QString fileName = QString::fromLocal8Bit(line.mid(27)).trimmed();
+ if (fileName != QLatin1String("modification.txt"))
+ continue;
bool ok;
int time = line.mid(18, 8).toUInt(&ok, 16);
if (!ok)
continue;
- QString fileName = QString::fromLocal8Bit(line.mid(27)).trimmed();
-
- ret[directory + QLatin1Char('/') + fileName] = QDateTime::fromTime_t(time);
-
- if (fileName != QLatin1String("..") && fileName != QLatin1String(".") && !fileName.isEmpty())
- possibleDirectoriesToTry.append(directory + QLatin1Char('/') + fileName);
+ options->remoteModificationDate = QDateTime::fromTime_t(time);
+ break;
}
- foreach (QString possibleDirectoryToTry, possibleDirectoriesToTry)
- fetchRemoteModifications(options, possibleDirectoryToTry);
-
pclose(adbCommand);
- options->remoteModificationDates.unite(ret);
+
+ {
+ QFile file(options->temporaryDirectoryName + QLatin1String("/modification.txt"));
+ if (!file.open(QIODevice::WriteOnly)) {
+ fprintf(stderr, "Cannot create modification timestamp.\n");
+ return false;
+ }
+ }
return true;
}
@@ -1451,20 +1458,10 @@ bool deployToLocalTmp(Options *options,
QFileInfo fileInfo(options->qtInstallDirectory + QLatin1Char('/') + qtDependency);
- QStringList unmetDependencies;
- if (!goodToCopy(options, fileInfo.absoluteFilePath(), &unmetDependencies)) {
- if (options->verbose)
- fprintf(stdout, " -- Skipping %s. It has unmet dependencies: %s.\n",
- qPrintable(fileInfo.absoluteFilePath()),
- qPrintable(unmetDependencies.join(QLatin1Char(','))));
- return true;
- }
-
// Make sure precision is the same as what we get from Android
QDateTime sourceModified = QDateTime::fromTime_t(fileInfo.lastModified().toTime_t());
- QDateTime destinationModified = options->remoteModificationDates.value(QLatin1String("/data/local/tmp/qt/") + qtDependency);
- if (destinationModified.isNull() || destinationModified < sourceModified) {
+ if (options->remoteModificationDate.isNull() || options->remoteModificationDate < sourceModified) {
if (!copyFileIfNewer(options->qtInstallDirectory + QLatin1Char('/') + qtDependency,
options->temporaryDirectoryName + QLatin1Char('/') + qtDependency,
options->verbose)) {
@@ -1475,26 +1472,6 @@ bool deployToLocalTmp(Options *options,
&& !stripFile(*options, options->temporaryDirectoryName + QLatin1Char('/') + qtDependency)) {
return false;
}
-
- FILE *adbCommand = runAdb(*options,
- QString::fromLatin1(" push %1 %2")
- .arg(options->temporaryDirectoryName + QLatin1Char('/') + qtDependency)
- .arg(QLatin1String("/data/local/tmp/qt/") + qtDependency));
- if (adbCommand == 0)
- return false;
-
- if (options->verbose) {
- fprintf(stdout, " -- Deploying %s to device.\n", qPrintable(qtDependency));
- char buffer[512];
- while (fgets(buffer, sizeof(buffer), adbCommand) != 0)
- fprintf(stdout, "%s", buffer);
- }
-
- int errorCode = pclose(adbCommand);
- if (errorCode != 0) {
- fprintf(stderr, "Copying file to device failed!\n");
- return false;
- }
}
return true;
@@ -1517,12 +1494,29 @@ bool copyQtFiles(Options *options)
}
if (options->deploymentMechanism == Options::Debug) {
- foreach (QString qtDependency, options->qtDependencies) {
- if (!deployToLocalTmp(options, qtDependency))
- return false;
+ // For debug deployment, we copy all libraries and plugins
+ QDirIterator dirIterator(options->qtInstallDirectory, QDirIterator::Subdirectories);
+ while (dirIterator.hasNext()) {
+ QFileInfo info = dirIterator.fileInfo();
+ if (!info.isDir()) {
+ QString relativePath = info.absoluteFilePath().mid(options->qtInstallDirectory.length());
+ if (relativePath.startsWith(QLatin1Char('/')))
+ relativePath.remove(0, 1);
+ if ((relativePath.startsWith("lib/") && relativePath.endsWith(".so"))
+ || relativePath.startsWith("jar/")
+ || relativePath.startsWith("plugins/")
+ || relativePath.startsWith("imports/")
+ || relativePath.startsWith("qml/")
+ || relativePath.startsWith("plugins/")) {
+ if (!deployToLocalTmp(options, relativePath))
+ return false;
+ }
+ }
+ dirIterator.next();
+ }
+ foreach (QString qtDependency, options->qtDependencies)
options->bundledFiles += qMakePair(qtDependency, qtDependency);
- }
} else {
QString libsDirectory = QLatin1String("libs/");
@@ -1954,6 +1948,30 @@ bool copyGdbServer(const Options &options)
return true;
}
+bool deployAllToLocalTmp(const Options &options)
+{
+ FILE *adbCommand = runAdb(options,
+ QString::fromLatin1(" push %1 /data/local/tmp/qt/")
+ .arg(options.temporaryDirectoryName + QLatin1Char('/')));
+ if (adbCommand == 0)
+ return false;
+
+ if (options.verbose) {
+ fprintf(stdout, " -- Deploying Qt files to device.\n");
+ char buffer[512];
+ while (fgets(buffer, sizeof(buffer), adbCommand) != 0)
+ fprintf(stdout, "%s", buffer);
+ }
+
+ int errorCode = pclose(adbCommand);
+ if (errorCode != 0) {
+ fprintf(stderr, "Copying files to device failed!\n");
+ return false;
+ }
+
+ return true;
+}
+
enum ErrorCode
{
Success,
@@ -1972,7 +1990,8 @@ enum ErrorCode
CannotCreateAndroidProject = 13,
CannotBuildAndroidProject = 14,
CannotSignPackage = 15,
- CannotInstallApk = 16
+ CannotInstallApk = 16,
+ CannotDeployAllToLocalTmp = 17
};
int main(int argc, char *argv[])
@@ -1985,9 +2004,15 @@ int main(int argc, char *argv[])
return SyntaxErrorOrHelpRequested;
}
+ if (Q_UNLIKELY(options.timing))
+ options.timer.start();
+
if (!readInputFile(&options))
return CannotReadInputFile;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Read input file\n", options.timer.elapsed());
+
fprintf(stdout,
// "012345678901234567890123456789012345678901234567890123456789012345678901"
"Generating Android Package\n"
@@ -2008,45 +2033,90 @@ int main(int argc, char *argv[])
if (!copyAndroidTemplate(options))
return CannotCopyAndroidTemplate;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Copied Android template\n", options.timer.elapsed());
+
if (!readDependencies(&options))
return CannotReadDependencies;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Read dependencies\n", options.timer.elapsed());
+
if (options.deploymentMechanism != Options::Ministro && !copyGnuStl(&options))
return CannotCopyGnuStl;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Copied GNU STL\n", options.timer.elapsed());
+
if (!copyQtFiles(&options))
return CannotCopyQtFiles;
+ if (options.deploymentMechanism == Options::Debug && !deployAllToLocalTmp(options))
+ return CannotDeployAllToLocalTmp;
+
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Copied Qt files\n", options.timer.elapsed());
+
if (!containsApplicationBinary(options))
return CannotFindApplicationBinary;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Checked for application binary\n", options.timer.elapsed());
+
if (!options.releasePackage && !copyGdbServer(options))
return CannotCopyGdbServer;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Copied GDB server\n", options.timer.elapsed());
+
if (!stripLibraries(options))
return CannotStripLibraries;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Stripped libraries\n", options.timer.elapsed());
+
if (!copyAndroidExtraLibs(options))
return CannotCopyAndroidExtraLibs;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Copied extra libs\n", options.timer.elapsed());
+
if (!copyAndroidSources(options))
return CannotCopyAndroidSources;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Copied android sources\n", options.timer.elapsed());
+
if (!updateAndroidFiles(options))
return CannotUpdateAndroidFiles;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Updated files\n", options.timer.elapsed());
+
if (!createAndroidProject(options))
return CannotCreateAndroidProject;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Created project\n", options.timer.elapsed());
+
if (!buildAndroidProject(options))
return CannotBuildAndroidProject;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Built project\n", options.timer.elapsed());
+
if (!options.keyStore.isEmpty() && !signPackage(options))
return CannotSignPackage;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Signed package\n", options.timer.elapsed());
+
if (options.installApk && !installApk(options))
return CannotInstallApk;
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Installed APK\n", options.timer.elapsed());
+
fprintf(stdout, "Android package built successfully.\n");
if (options.installApk)
diff --git a/src/designer/src/components/formeditor/formwindow.cpp b/src/designer/src/components/formeditor/formwindow.cpp
index 9ac7fb55b..d26b5d5ba 100644
--- a/src/designer/src/components/formeditor/formwindow.cpp
+++ b/src/designer/src/components/formeditor/formwindow.cpp
@@ -2159,6 +2159,7 @@ bool FormWindow::setContents(QIODevice *dev, QString *errorMessageIn /* = 0 */)
// The main container is cleared as otherwise
// the names of the newly loaded objects will be unified.
clearMainContainer();
+ m_undoStack.clear();
emit changed();
QDesignerResource r(this);
diff --git a/src/designer/src/components/formeditor/qdesignerundostack.cpp b/src/designer/src/components/formeditor/qdesignerundostack.cpp
index 48c36fc5f..cc533f9b6 100644
--- a/src/designer/src/components/formeditor/qdesignerundostack.cpp
+++ b/src/designer/src/components/formeditor/qdesignerundostack.cpp
@@ -60,6 +60,12 @@ QDesignerUndoStack::~QDesignerUndoStack()
{ // QUndoStack is managed by the QUndoGroup
}
+void QDesignerUndoStack::clear()
+{
+ m_fakeDirty = false;
+ m_undoStack->clear();
+}
+
void QDesignerUndoStack::push(QUndoCommand * cmd)
{
m_undoStack->push(cmd);
diff --git a/src/designer/src/components/formeditor/qdesignerundostack.h b/src/designer/src/components/formeditor/qdesignerundostack.h
index 01f3d29e3..84d56184e 100644
--- a/src/designer/src/components/formeditor/qdesignerundostack.h
+++ b/src/designer/src/components/formeditor/qdesignerundostack.h
@@ -62,6 +62,7 @@ public:
explicit QDesignerUndoStack(QObject *parent = 0);
virtual ~QDesignerUndoStack();
+ void clear();
void push(QUndoCommand * cmd);
void beginMacro(const QString &text);
void endMacro();
diff --git a/src/macdeployqt/macchangeqt/main.cpp b/src/macdeployqt/macchangeqt/main.cpp
index 341f1c248..495c305d1 100644
--- a/src/macdeployqt/macchangeqt/main.cpp
+++ b/src/macdeployqt/macchangeqt/main.cpp
@@ -65,7 +65,7 @@ int main(int argc, char **argv)
}
if (argc != (3 + optionsSpecified)) {
- qDebug() << "Changeqt: changes witch Qt frameworks an application links against.";
+ qDebug() << "Changeqt: changes which Qt frameworks an application links against.";
qDebug() << "Usage: changeqt app-bundle qt-dir <-verbose=[0-3]>";
return 0;
}
diff --git a/src/qdbus/qdbus/qdbus.cpp b/src/qdbus/qdbus/qdbus.cpp
index 0349c6008..b03c14319 100644
--- a/src/qdbus/qdbus/qdbus.cpp
+++ b/src/qdbus/qdbus/qdbus.cpp
@@ -479,9 +479,15 @@ int main(int argc, char **argv)
connection = QDBusConnection::sessionBus();
if (!connection.isConnected()) {
- fprintf(stderr, "Could not connect to D-Bus server: %s: %s\n",
- qPrintable(connection.lastError().name()),
- qPrintable(connection.lastError().message()));
+ const QDBusError lastError = connection.lastError();
+ if (lastError.isValid()) {
+ fprintf(stderr, "Could not connect to D-Bus server: %s: %s\n",
+ qPrintable(lastError.name()),
+ qPrintable(lastError.message()));
+ } else {
+ // an invalid last error means that we were not able to even load the D-Bus library
+ fprintf(stderr, "Could not connect to D-Bus server: Unable to load dbus libraries\n");
+ }
return 1;
}
diff --git a/src/windeployqt/main.cpp b/src/windeployqt/main.cpp
index dc57f340b..a5e5a9283 100644
--- a/src/windeployqt/main.cpp
+++ b/src/windeployqt/main.cpp
@@ -182,7 +182,7 @@ bool optHelp = false;
int optWebKit2 = 0;
struct Options {
- Options() : plugins(true), libraries(true), quickImports(true), translations(true)
+ Options() : plugins(true), libraries(true), quickImports(true), translations(true), systemD3dCompiler(true)
, platform(Windows), additionalLibraries(0), disabledLibraries(0)
, updateFileFlags(0), json(0) {}
@@ -190,6 +190,7 @@ struct Options {
bool libraries;
bool quickImports;
bool translations;
+ bool systemD3dCompiler;
Platform platform;
unsigned additionalLibraries;
unsigned disabledLibraries;
@@ -266,6 +267,10 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse
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 webKitOption(QStringLiteral("webkit2"),
QStringLiteral("Deployment of WebKit2 (web process)."));
parser->addOption(webKitOption);
@@ -316,6 +321,7 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse
options->plugins = !parser->isSet(noPluginsOption);
options->libraries = !parser->isSet(noLibraryOption);
options->translations = !parser->isSet(noTranslationOption);
+ options->systemD3dCompiler = !parser->isSet(noSystemD3DCompilerOption);
options->quickImports = !parser->isSet(noQuickImportOption);
if (parser->isSet(forceOption))
options->updateFileFlags |= ForceUpdateFile;
@@ -480,7 +486,7 @@ private:
class QmlDirectoryFileEntryFunction {
public:
explicit QmlDirectoryFileEntryFunction(Platform platform, bool debug)
- : m_qmlNameFilter(QStringList() << QStringLiteral("*.js") << QStringLiteral("qmldir") << QStringLiteral("*.qmltypes") << QStringLiteral("*.png"))
+ : m_qmlNameFilter(QStringList() << QStringLiteral("*.js") << QStringLiteral("qmldir") << QStringLiteral("*.qml") << QStringLiteral("*.qmltypes") << QStringLiteral("*.png"))
, m_dllFilter(platform, debug)
{}
@@ -652,6 +658,16 @@ static QString libraryPath(const QString &libraryLocation, const char *name, Pla
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;
+}
+
static DeployResult deploy(const Options &options,
const QMap<QString, QString> &qmakeVariables,
QString *errorMessage)
@@ -662,6 +678,7 @@ static DeployResult deploy(const Options &options,
const QString qtBinDir = qmakeVariables.value(QStringLiteral("QT_INSTALL_BINS"));
const QString libraryLocation = options.platform == Unix ? qmakeVariables.value(QStringLiteral("QT_INSTALL_LIBS")) : qtBinDir;
+ const int version = qtVersion(qmakeVariables);
if (optVerboseLevel > 1)
std::printf("Qt binaries in %s\n", qPrintable(QDir::toNativeSeparators(qtBinDir)));
@@ -746,8 +763,8 @@ static DeployResult deploy(const Options &options,
}
if (optVerboseLevel >= 1) {
std::fputs("QML imports:\n", stdout);
- foreach (const QString &mod, qmlScanResult.modulesDirectories)
- std::printf(" %s\n", qPrintable(QDir::toNativeSeparators(mod)));
+ foreach (const QmlImportScanResult::Module &mod, qmlScanResult.modules)
+ std::printf(" '%s' %s\n", qPrintable(mod.name), qPrintable(QDir::toNativeSeparators(mod.sourcePath)));
if (optVerboseLevel >= 2) {
std::fputs("QML plugins:\n", stdout);
foreach (const QString &p, qmlScanResult.plugins)
@@ -804,12 +821,23 @@ static DeployResult deploy(const Options &options,
const QString libGLESv2FullPath = qtBinDir + slash + QFileInfo(libGLESv2.front()).fileName();
deployedQtLibraries.push_back(libGLESv2FullPath);
}
- // Find the D3d Compiler matching the D3D library.
- const QString d3dCompiler = findD3dCompiler(options.platform, wordSize);
- if (d3dCompiler.isEmpty()) {
- std::fprintf(stderr, "Warning: Cannot find any version of the d3dcompiler DLL.\n");
- } else {
- deployedQtLibraries.push_back(d3dCompiler);
+ // Find the system D3d Compiler matching the D3D library.
+ if (options.systemD3dCompiler && options.platform != WinPhoneArm && options.platform != WinPhoneIntel) {
+ const QString d3dCompiler = findD3dCompiler(options.platform, wordSize);
+ if (d3dCompiler.isEmpty()) {
+ std::fprintf(stderr, "Warning: Cannot find any version of the d3dcompiler DLL.\n");
+ } else {
+ deployedQtLibraries.push_back(d3dCompiler);
+ }
+ }
+ // Deploy Qt's D3D compiler starting from 5.3 onwards.
+ if (version >= 0x050300) {
+ QString d3dCompilerQt = qtBinDir + QStringLiteral("/d3dcompiler_qt");
+ if (isDebug)
+ d3dCompilerQt += QLatin1Char('d');
+ d3dCompilerQt += QLatin1String(windowsSharedLibrarySuffix);
+ if (QFileInfo(d3dCompilerQt).exists())
+ deployedQtLibraries.push_back(d3dCompilerQt);
}
} // !libEgl.isEmpty()
} // Windows
@@ -851,8 +879,14 @@ static DeployResult deploy(const Options &options,
if (options.quickImports && (usesQuick1 || usesQml2)) {
const QmlDirectoryFileEntryFunction qmlFileEntryFunction(options.platform, isDebug);
if (usesQml2) {
- foreach (const QString &module, qmlScanResult.modulesDirectories) {
- if (!updateFile(module, qmlFileEntryFunction, options.directory, options.updateFileFlags, options.json, errorMessage))
+ foreach (const QmlImportScanResult::Module &module, qmlScanResult.modules) {
+ const QString installPath = module.installPath(options.directory);
+ if (optVerboseLevel > 1)
+ std::printf("Installing: '%s' from %s to %s\n",
+ qPrintable(module.name), qPrintable(module.sourcePath), qPrintable(QDir::toNativeSeparators(installPath)));
+ if (installPath != options.directory && !createDirectory(installPath, errorMessage))
+ return result;
+ if (!updateFile(module.sourcePath, qmlFileEntryFunction, installPath, options.updateFileFlags, options.json, errorMessage))
return result;
}
} // Quick 2
diff --git a/src/windeployqt/qmlutils.cpp b/src/windeployqt/qmlutils.cpp
index 8e16a9526..aef736364 100644
--- a/src/windeployqt/qmlutils.cpp
+++ b/src/windeployqt/qmlutils.cpp
@@ -52,6 +52,41 @@
QT_BEGIN_NAMESPACE
+// Return the relative install path, that is, for example for
+// module "QtQuick.Controls.Styles" in "path/qtbase/qml/QtQuick/Controls/Styles.3"
+// --> "QtQuick/Controls" suitable for updateFile() (cp -r semantics).
+QString QmlImportScanResult::Module::relativeInstallPath() const
+{
+ const QChar dot = QLatin1Char('.');
+ const QChar slash = QLatin1Char('/');
+
+ // Find relative path by module name.
+ if (!name.contains(dot))
+ return QString(); // "QtQuick.2" -> flat folder.
+ QString result = sourcePath;
+ QString pathComponent = name;
+ pathComponent.replace(dot, slash);
+ const int pos = result.lastIndexOf(pathComponent);
+ if (pos < 0)
+ return QString();
+ result.remove(0, pos);
+ // return base name.
+ const int lastSlash = result.lastIndexOf(slash);
+ if (lastSlash >= 0)
+ result.truncate(lastSlash);
+ return result;
+}
+
+QString QmlImportScanResult::Module::installPath(const QString &root) const
+{
+ QString result = root;
+ const QString relPath = relativeInstallPath();
+ if (!relPath.isEmpty())
+ result += QLatin1Char('/');
+ result += relPath;
+ return result;
+}
+
static QString qmlDirectoryRecursion(Platform platform, const QString &path)
{
QDir dir(path);
@@ -119,7 +154,11 @@ QmlImportScanResult runQmlImportScanner(const QString &directory, const QString
if (object.value(QStringLiteral("type")).toString() == QLatin1String("module")) {
const QString path = object.value(QStringLiteral("path")).toString();
if (!path.isEmpty()) {
- result.modulesDirectories.append(path);
+ QmlImportScanResult::Module module;
+ module.name = object.value(QStringLiteral("name")).toString();
+ module.className = object.value(QStringLiteral("classname")).toString();
+ module.sourcePath = path;
+ result.modules.append(module);
findFileRecursion(QDir(path), Platform(platform), debug, &result.plugins);
}
}
@@ -128,14 +167,23 @@ QmlImportScanResult runQmlImportScanner(const QString &directory, const QString
return result;
}
+static inline bool contains(const QList<QmlImportScanResult::Module> &modules, const QString &name)
+{
+ foreach (const QmlImportScanResult::Module &m, modules) {
+ if (m.name == name)
+ return true;
+ }
+ return false;
+}
+
void QmlImportScanResult::append(const QmlImportScanResult &other)
{
- foreach (const QString &module, other.modulesDirectories) {
- if (!modulesDirectories.contains(module))
- modulesDirectories.append(module);
+ foreach (const QmlImportScanResult::Module &module, other.modules) {
+ if (!contains(modules, module.name))
+ modules.append(module);
}
foreach (const QString &plugin, other.plugins) {
- if (!plugin.contains(plugin))
+ if (!plugins.contains(plugin))
plugins.append(plugin);
}
}
diff --git a/src/windeployqt/qmlutils.h b/src/windeployqt/qmlutils.h
index ea8c7747d..1752d2717 100644
--- a/src/windeployqt/qmlutils.h
+++ b/src/windeployqt/qmlutils.h
@@ -49,11 +49,20 @@ QT_BEGIN_NAMESPACE
QString findQmlDirectory(int platform, const QString &startDirectoryName);
struct QmlImportScanResult {
+ struct Module {
+ QString relativeInstallPath() const;
+ QString installPath(const QString &root) const;
+
+ QString name;
+ QString className;
+ QString sourcePath;
+ };
+
QmlImportScanResult() : ok(false) {}
void append(const QmlImportScanResult &other);
bool ok;
- QStringList modulesDirectories;
+ QList<Module> modules;
QStringList plugins;
};
diff --git a/src/windeployqt/utils.cpp b/src/windeployqt/utils.cpp
index 36edf5e35..527a6e9d0 100644
--- a/src/windeployqt/utils.cpp
+++ b/src/windeployqt/utils.cpp
@@ -474,14 +474,14 @@ QMap<QString, QString> queryQMakeAll(QString *errorMessage)
}
const QString output = QString::fromLocal8Bit(stdOut).trimmed().remove(QLatin1Char('\r'));
QMap<QString, QString> result;
- int pos = 0;
- while (true) {
+ const int size = output.size();
+ for (int pos = 0; pos < size; ) {
const int colonPos = output.indexOf(QLatin1Char(':'), pos);
if (colonPos < 0)
break;
- const int endPos = output.indexOf(QLatin1Char('\n'), colonPos + 1);
+ int endPos = output.indexOf(QLatin1Char('\n'), colonPos + 1);
if (endPos < 0)
- break;
+ endPos = size;
const QString key = output.mid(pos, colonPos - pos);
const QString value = output.mid(colonPos + 1, endPos - colonPos - 1);
result.insert(key, value);