summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
authorRaphael Cotty <raphael.cotty@gmail.com>2021-09-17 20:43:38 +0200
committerAndreas Buhr <andreas.buhr@qt.io>2021-10-01 18:51:07 +0200
commitcdfcb98bc0a06eba3be395f225e9397946058591 (patch)
tree415350337fe4701c821471e7b0da96c2934a9dd6 /src/tools
parent9875869d3174cf0f15ebfccac427ade3cb01e046 (diff)
androiddeployqt: Allow to also provide multiple qt install directories
The "qt" property can also be filled with a json object like this: "qt": { "x86":"/home/.../Qt/6.3.0/android_x86", "x86_64":"/home/.../Qt/6.3.0/android_x86_64", "arm64-v8a":"/home/.../Qt/6.3.0/android_arm64_v8a", "armeabi-v7a":"/home/.../Qt/6.3.0/android_armv7"} That allows to update the options.qtInstallDirectory when changing the current architecture. The "qtHostDir" property is also added to provide the path to the qt host installation (rcc, qmlimportscanner). Change-Id: I3f0c36cc7a7030d45adc1a4dccaaad61dd538aea Task-number: QTBUG-88841 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/androiddeployqt/main.cpp108
1 files changed, 91 insertions, 17 deletions
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index b88e772fc8..57f51ba1bd 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -118,6 +118,16 @@ struct QtDependency
QString absolutePath;
};
+struct QtInstallDirectoryWithTriple
+{
+ QtInstallDirectoryWithTriple(const QString &dir = QString(), const QString &t = QString()) :
+ qtInstallDirectory(dir), triple(t), enabled(false) {}
+
+ QString qtInstallDirectory;
+ QString triple;
+ bool enabled;
+};
+
struct Options
{
Options()
@@ -165,6 +175,7 @@ struct Options
// Build paths
QString qtInstallDirectory;
+ QString qtHostDirectory;
std::vector<QString> extraPrefixDirs;
// Unlike 'extraPrefixDirs', the 'extraLibraryDirs' key doesn't expect the 'lib' subfolder
// when looking for dependencies.
@@ -193,7 +204,7 @@ struct Options
// Build information
QString androidPlatform;
- QHash<QString, QString> architectures;
+ QHash<QString, QtInstallDirectoryWithTriple> architectures;
QString currentArchitecture;
QString toolchainPrefix;
QString ndkHost;
@@ -234,9 +245,10 @@ struct Options
QString installLocation;
// Per architecture collected information
- void clear(const QString &arch)
+ void setCurrentQtArchitecture(const QString &arch, const QString &directory)
{
currentArchitecture = arch;
+ qtInstallDirectory = directory;
}
typedef QPair<QString, QString> BundledFile;
QHash<QString, QList<BundledFile>> bundledFiles;
@@ -913,7 +925,50 @@ bool readInputFile(Options *options)
fprintf(stderr, "No Qt directory in json file %s\n", qPrintable(options->inputFileName));
return false;
}
- options->qtInstallDirectory = qtInstallDirectory.toString();
+
+ if (qtInstallDirectory.isObject()) {
+ const QJsonObject object = qtInstallDirectory.toObject();
+ for (auto it = object.constBegin(); it != object.constEnd(); ++it) {
+ if (it.value().isUndefined()) {
+ fprintf(stderr, "Invalid architecture: %s\n",
+ qPrintable(it.value().toString()));
+ return false;
+ }
+ if (it.value().isNull())
+ continue;
+ options->architectures.insert(it.key(),
+ QtInstallDirectoryWithTriple(it.value().toString()));
+ }
+ } else if (qtInstallDirectory.isString()) {
+ // Format for Qt < 6 or when using the tool with Qt >= 6 but in single arch.
+ // We assume Qt > 5.14 where all architectures are in the same directory.
+ const QString directory = qtInstallDirectory.toString();
+ QtInstallDirectoryWithTriple qtInstallDirectoryWithTriple(directory);
+ options->architectures.insert(QLatin1String("arm64-v8a"), qtInstallDirectoryWithTriple);
+ options->architectures.insert(QLatin1String("armeabi-v7a"), qtInstallDirectoryWithTriple);
+ options->architectures.insert(QLatin1String("x86"), qtInstallDirectoryWithTriple);
+ options->architectures.insert(QLatin1String("x86_64"), qtInstallDirectoryWithTriple);
+ // In Qt < 6 rcc and qmlimportscanner are installed in the host and install directories
+ // In Qt >= 6 rcc and qmlimportscanner are only installed in the host directory
+ // So setting the "qtHostDir" is not necessary with Qt < 6.
+ options->qtHostDirectory = directory;
+ } else {
+ fprintf(stderr, "Invalid format for Qt install prefixes in json file %s.\n",
+ qPrintable(options->inputFileName));
+ return false;
+ }
+ }
+ {
+ const QJsonValue qtHostDirectory = jsonObject.value(QLatin1String("qtHostDir"));
+ if (!qtHostDirectory.isUndefined()) {
+ if (qtHostDirectory.isString()) {
+ options->qtHostDirectory = qtHostDirectory.toString();
+ } else {
+ fprintf(stderr, "Invalid format for Qt host directory in json file %s.\n",
+ qPrintable(options->inputFileName));
+ return false;
+ }
+ }
}
{
@@ -987,7 +1042,13 @@ bool readInputFile(Options *options)
}
if (it.value().isNull())
continue;
- options->architectures.insert(it.key(), it.value().toString());
+ if (!options->architectures.contains(it.key())) {
+ fprintf(stderr, "Architecture %s unknown (%s).", qPrintable(it.key()),
+ qPrintable(options->architectures.keys().join(QLatin1Char(','))));
+ return false;
+ }
+ options->architectures[it.key()].triple = it.value().toString();
+ options->architectures[it.key()].enabled = true;
}
}
@@ -1081,6 +1142,8 @@ bool readInputFile(Options *options)
options->applicationBinary = applicationBinary.toString();
if (options->build) {
for (auto it = options->architectures.constBegin(); it != options->architectures.constEnd(); ++it) {
+ if (!it->enabled)
+ continue;
auto appBinaryPath = QLatin1String("%1/libs/%2/lib%3_%2.so").arg(options->outputDirectory, it.key(), options->applicationBinary);
if (!QFile::exists(appBinaryPath)) {
fprintf(stderr, "Cannot find application binary in build dir %s.\n", qPrintable(appBinaryPath));
@@ -1101,7 +1164,8 @@ bool readInputFile(Options *options)
if (QFileInfo(path).isDir()) {
QDirIterator iterator(path, QDirIterator::Subdirectories);
while (iterator.hasNext()) {
- if (iterator.nextFileInfo().isFile()) {
+ iterator.next();
+ if (iterator.fileInfo().isFile()) {
QString subPath = iterator.filePath();
auto arch = fileArchitecture(*options, subPath);
if (!arch.isEmpty()) {
@@ -1401,6 +1465,8 @@ bool updateLibsXml(Options *options)
QString extraLibs;
for (auto it = options->architectures.constBegin(); it != options->architectures.constEnd(); ++it) {
+ if (!it->enabled)
+ continue;
QString libsPath = QLatin1String("libs/") + it.key() + QLatin1Char('/');
qtLibs += QLatin1String(" <item>%1;%2</item>\n").arg(it.key(), options->stdCppName);
@@ -2739,7 +2805,9 @@ bool copyStdCpp(Options *options)
if (options->verbose)
fprintf(stdout, "Copying STL library\n");
- QString stdCppPath = QLatin1String("%1/%2/lib%3.so").arg(options->stdCppPath, options->architectures[options->currentArchitecture], options->stdCppName);
+ const QString triple = options->architectures[options->currentArchitecture].triple;
+ const QString stdCppPath = QLatin1String("%1/%2/lib%3.so").arg(options->stdCppPath, triple,
+ options->stdCppName);
if (!QFile::exists(stdCppPath)) {
fprintf(stderr, "STL library does not exist at %s\n", qPrintable(stdCppPath));
fflush(stdout);
@@ -3095,20 +3163,26 @@ int main(int argc, char *argv[])
: "No"
);
- if (options.build && !options.auxMode) {
- cleanAndroidFiles(options);
- if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Cleaned Android file\n", options.timer.elapsed());
+ bool androidTemplatetCopied = false;
+
+ for (auto it = options.architectures.constBegin(); it != options.architectures.constEnd(); ++it) {
+ if (!it->enabled)
+ continue;
+ options.setCurrentQtArchitecture(it.key(), it.value().qtInstallDirectory);
- if (!copyAndroidTemplate(options))
- return CannotCopyAndroidTemplate;
+ // All architectures have a copy of the gradle files but only one set needs to be copied.
+ if (!androidTemplatetCopied && options.build && !options.auxMode) {
+ cleanAndroidFiles(options);
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Cleaned Android file\n", options.timer.elapsed());
- if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Copied Android template\n", options.timer.elapsed());
- }
+ if (!copyAndroidTemplate(options))
+ return CannotCopyAndroidTemplate;
- for (auto it = options.architectures.constBegin(); it != options.architectures.constEnd(); ++it) {
- options.clear(it.key());
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Copied Android template\n", options.timer.elapsed());
+ androidTemplatetCopied = true;
+ }
if (!readDependencies(&options))
return CannotReadDependencies;