diff options
author | BogDan Vatra <bogdan@kde.org> | 2020-01-20 11:20:09 +0200 |
---|---|---|
committer | BogDan Vatra <bogdan@kdab.com> | 2020-01-20 17:18:36 +0000 |
commit | 12c74e6664bc910b40de7fb96a163d511711b7b1 (patch) | |
tree | 003bb7cb0f02243e219659766d6466902dc273c6 | |
parent | 07544d4e0721e1ddbed3d310e6d250333c2b1fb5 (diff) | |
download | qt-creator-12c74e6664bc910b40de7fb96a163d511711b7b1.tar.gz |
Handle Qt < 5.14.0 androiddeployqt settings file
This file is needed by cmake projects.
Fixes: QTCREATORBUG-23306
Change-Id: Ie0ffd325ca01ac5638620c258d5e8ed5bbd3259e
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
-rw-r--r-- | src/plugins/android/androidbuildapkstep.cpp | 79 | ||||
-rw-r--r-- | src/plugins/android/androidbuildapkstep.h | 1 | ||||
-rw-r--r-- | src/plugins/android/androidmanager.cpp | 43 | ||||
-rw-r--r-- | src/plugins/android/androidmanager.h | 2 |
4 files changed, 84 insertions, 41 deletions
diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index ccd9bec14d..b2bb8849d3 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -221,11 +221,10 @@ bool AndroidBuildApkStep::init() QString outputDir = bc->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY).toString(); - QString inputFile; if (node) - inputFile = node->data(Constants::AndroidDeploySettingsFile).toString(); + m_inputFile = node->data(Constants::AndroidDeploySettingsFile).toString(); - if (inputFile.isEmpty()) { + if (m_inputFile.isEmpty()) { m_skipBuilding = true; return true; } @@ -237,7 +236,7 @@ bool AndroidBuildApkStep::init() return false; } - QStringList arguments = {"--input", inputFile, + QStringList arguments = {"--input", m_inputFile, "--output", outputDir, "--android-platform", AndroidManager::buildTargetSDK(target()), "--jdk", AndroidConfigurations::currentConfig().openJDKLocation().toString()}; @@ -353,6 +352,8 @@ bool AndroidBuildApkStep::verifyCertificatePassword() static bool copyFileIfNewer(const QString &sourceFileName, const QString &destinationFileName) { + if (sourceFileName == destinationFileName) + return true; if (QFile::exists(destinationFileName)) { QFileInfo destinationFileInfo(destinationFileName); QFileInfo sourceFileInfo(sourceFileName); @@ -393,48 +394,56 @@ void AndroidBuildApkStep::doRun() if (!node) return false; - FilePath deploymentSettingsFile = FilePath::fromString(node->data(Android::Constants::AndroidDeploySettingsFile).toString()); - if (deploymentSettingsFile.exists()) - return true; // cmake creates this file for us + bool inputExists = QFile::exists(m_inputFile); + if (inputExists && !AndroidManager::isQtCreatorGenerated(FilePath::fromString(m_inputFile))) + return true; // use the generated file if it was not generated by qtcreator auto targets = node->data(Android::Constants::AndroidTargets).toStringList(); if (targets.isEmpty()) - return true; // qmake does this job for us + return inputExists; // qmake does this job for us - QJsonObject deploySettings = Android::AndroidManager::deploymentSettings(target()); - QJsonObject architectures; - // Copy targets to android build folder - QString applicationBinary = target()->activeRunConfiguration()->buildTargetInfo().targetFilePath.toFileInfo().fileName(); - for (const auto &abi : androidAbis) { - QString targetSuffix = QString{"_%1.so"}.arg(abi); - if (applicationBinary.endsWith(targetSuffix)) { - // Keep only TargetName from "lib[TargetName]_abi.so" - applicationBinary.remove(0, 3).chop(targetSuffix.size()); - } + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(target()->kit()); + if (!version) + return false; - Utils::FilePath androidLibsDir = bc->buildDirectory() - .pathAppended("android-build/libs") - .pathAppended(abi); + QJsonObject deploySettings = Android::AndroidManager::deploymentSettings(target()); + QString applicationBinary; + if (version->qtVersion() < QtSupport::QtVersionNumber(5, 14, 0)) { + QTC_ASSERT(androidAbis.size() == 1, return false); + applicationBinary = target()->activeRunConfiguration()->buildTargetInfo().targetFilePath.toString(); + Utils::FilePath androidLibsDir = bc->buildDirectory().pathAppended("android-build/libs").pathAppended(androidAbis.first()); for (const auto &target : targets) { - if (target.endsWith(targetSuffix)) { - if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString())) - return false; - if (abi == "x86") { - architectures[abi] = "i686-linux-android"; - } else if (abi == "x86_64") { - architectures[abi] = "x86_64-linux-android"; - } else if (abi == "arm64-v8a") { - architectures[abi] = "aarch64-linux-android"; - } else { - architectures[abi] = "arm-linux-androideabi"; + if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString())) + return false; + } + deploySettings["target-architecture"] = androidAbis.first(); + } else { + applicationBinary = target()->activeRunConfiguration()->buildTargetInfo().targetFilePath.toFileInfo().fileName(); + QJsonObject architectures; + + // Copy targets to android build folder + for (const auto &abi : androidAbis) { + QString targetSuffix = QString{"_%1.so"}.arg(abi); + if (applicationBinary.endsWith(targetSuffix)) { + // Keep only TargetName from "lib[TargetName]_abi.so" + applicationBinary.remove(0, 3).chop(targetSuffix.size()); + } + + Utils::FilePath androidLibsDir = bc->buildDirectory() + .pathAppended("android-build/libs") + .pathAppended(abi); + for (const auto &target : targets) { + if (target.endsWith(targetSuffix)) { + if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString())) + return false; + architectures[abi] = AndroidManager::archTriplet(abi); } } } + deploySettings["architectures"] = architectures; } - deploySettings["application-binary"] = applicationBinary; - deploySettings["architectures"] = architectures; QString extraLibs = node->data(Android::Constants::AndroidExtraLibs).toString(); if (!extraLibs.isEmpty()) @@ -453,7 +462,7 @@ void AndroidBuildApkStep::doRun() qmlRootPath = target()->project()->rootProjectDirectory().toString(); deploySettings["qml-root-path"] = qmlRootPath; - QFile f{deploymentSettingsFile.toString()}; + QFile f{m_inputFile}; if (!f.open(QIODevice::WriteOnly)) return false; f.write(QJsonDocument{deploySettings}.toJson()); diff --git a/src/plugins/android/androidbuildapkstep.h b/src/plugins/android/androidbuildapkstep.h index 2ed137ccc3..f7f8b06999 100644 --- a/src/plugins/android/androidbuildapkstep.h +++ b/src/plugins/android/androidbuildapkstep.h @@ -110,6 +110,7 @@ private: QString m_command; QString m_argumentsPasswordConcealed; bool m_skipBuilding = false; + QString m_inputFile; }; namespace Internal { diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index d883496e6c..29c4f4e6eb 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -54,17 +54,18 @@ #include <utils/qtcassert.h> #include <utils/synchronousprocess.h> +#include <QApplication> #include <QDir> +#include <QDomDocument> #include <QFileSystemWatcher> +#include <QJsonDocument> #include <QList> #include <QLoggingCategory> +#include <QMessageBox> #include <QProcess> #include <QRegExp> -#include <QMessageBox> -#include <QApplication> -#include <QDomDocument> -#include <QVersionNumber> #include <QRegularExpression> +#include <QVersionNumber> namespace { const QLatin1String AndroidManifestName("AndroidManifest.xml"); @@ -76,6 +77,7 @@ namespace { const QString activityRegEx("(?<token>launchable-activity: )(.*?)(name=)'(?<target>.*?)'"); const QString apkVersionRegEx("(?<token>package: )(.*?)(versionCode=)'(?<target>.*?)'"); const QString versionCodeRegEx("(?<token>versionCode=)(?<version>\\d*)"); + const QString qtcSignature("This file is generated by QtCreator to be read by androiddeployqt and should not be modified by hand."); Q_LOGGING_CATEGORY(androidManagerLog, "qtc.android.androidManager", QtWarningMsg) @@ -264,6 +266,18 @@ QStringList AndroidManager::applicationAbis(const Target *target) return qt->androidAbis(); } +QString AndroidManager::archTriplet(const QString &abi) +{ + if (abi == "x86") { + return "i686-linux-android"; + } else if (abi == "x86_64") { + return "x86_64-linux-android"; + } else if (abi == "arm64-v8a") { + return "aarch64-linux-android"; + } + return "arm-linux-androideabi"; +} + QJsonObject AndroidManager::deploymentSettings(const Target *target) { QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(target->kit()); @@ -274,11 +288,20 @@ QJsonObject AndroidManager::deploymentSettings(const Target *target) if (!tc || tc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID) return {}; QJsonObject settings; - settings["_description"] = "This file is generated by QtCreator to be read by androiddeployqt and should not be modified by hand."; + settings["_description"] = qtcSignature; settings["qt"] = qt->prefix().toString(); settings["ndk"] = AndroidConfigurations::currentConfig().ndkLocation().toString(); settings["sdk"] = AndroidConfigurations::currentConfig().sdkLocation().toString(); - settings["stdcpp-path"] = AndroidConfigurations::currentConfig().toolchainPath().pathAppended("sysroot/usr/lib/").toString(); + if (qt->qtVersion() < QtSupport::QtVersionNumber(5, 14, 0)) { + const QStringList abis = applicationAbis(target); + QTC_ASSERT(abis.size() == 1, return {}); + settings["stdcpp-path"] = AndroidConfigurations::currentConfig().toolchainPath() + .pathAppended("sysroot/usr/lib/") + .pathAppended(archTriplet(abis.first())) + .pathAppended("libc++_shared.so").toString(); + } else { + settings["stdcpp-path"] = AndroidConfigurations::currentConfig().toolchainPath().pathAppended("sysroot/usr/lib/").toString(); + } settings["toolchain-prefix"] = "llvm"; settings["tool-prefix"] = "llvm"; settings["useLLVM"] = true; @@ -286,6 +309,14 @@ QJsonObject AndroidManager::deploymentSettings(const Target *target) return settings; } +bool AndroidManager::isQtCreatorGenerated(const FilePath &deploymentFile) +{ + QFile f{deploymentFile.toString()}; + if (!f.open(QIODevice::ReadOnly)) + return false; + return QJsonDocument::fromJson(f.readAll()).object()["_description"].toString() == qtcSignature; +} + Utils::FilePath AndroidManager::dirPath(const ProjectExplorer::Target *target) { if (auto *bc = target->activeBuildConfiguration()) diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index 49fc786b5f..ac94fdbdc3 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -96,6 +96,7 @@ public: static int minimumSDK(const ProjectExplorer::Kit *kit); static QStringList applicationAbis(const ProjectExplorer::Target *target); + static QString archTriplet(const QString &abi); static Utils::FilePath dirPath(const ProjectExplorer::Target *target); static Utils::FilePath manifestPath(ProjectExplorer::Target *target); @@ -127,6 +128,7 @@ public: static SdkToolResult runAaptCommand(const QStringList &args, int timeoutS = 30); static QJsonObject deploymentSettings(const ProjectExplorer::Target *target); + static bool isQtCreatorGenerated(const Utils::FilePath &deploymentFile); private: static SdkToolResult runCommand(const Utils::CommandLine &command, |