forked from qt-creator/qt-creator
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>
This commit is contained in:
committed by
BogDan Vatra
parent
07544d4e07
commit
12c74e6664
@@ -221,11 +221,10 @@ bool AndroidBuildApkStep::init()
|
|||||||
|
|
||||||
QString outputDir = bc->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY).toString();
|
QString outputDir = bc->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY).toString();
|
||||||
|
|
||||||
QString inputFile;
|
|
||||||
if (node)
|
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;
|
m_skipBuilding = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -237,7 +236,7 @@ bool AndroidBuildApkStep::init()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList arguments = {"--input", inputFile,
|
QStringList arguments = {"--input", m_inputFile,
|
||||||
"--output", outputDir,
|
"--output", outputDir,
|
||||||
"--android-platform", AndroidManager::buildTargetSDK(target()),
|
"--android-platform", AndroidManager::buildTargetSDK(target()),
|
||||||
"--jdk", AndroidConfigurations::currentConfig().openJDKLocation().toString()};
|
"--jdk", AndroidConfigurations::currentConfig().openJDKLocation().toString()};
|
||||||
@@ -353,6 +352,8 @@ bool AndroidBuildApkStep::verifyCertificatePassword()
|
|||||||
static bool copyFileIfNewer(const QString &sourceFileName,
|
static bool copyFileIfNewer(const QString &sourceFileName,
|
||||||
const QString &destinationFileName)
|
const QString &destinationFileName)
|
||||||
{
|
{
|
||||||
|
if (sourceFileName == destinationFileName)
|
||||||
|
return true;
|
||||||
if (QFile::exists(destinationFileName)) {
|
if (QFile::exists(destinationFileName)) {
|
||||||
QFileInfo destinationFileInfo(destinationFileName);
|
QFileInfo destinationFileInfo(destinationFileName);
|
||||||
QFileInfo sourceFileInfo(sourceFileName);
|
QFileInfo sourceFileInfo(sourceFileName);
|
||||||
@@ -393,48 +394,56 @@ void AndroidBuildApkStep::doRun()
|
|||||||
if (!node)
|
if (!node)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FilePath deploymentSettingsFile = FilePath::fromString(node->data(Android::Constants::AndroidDeploySettingsFile).toString());
|
bool inputExists = QFile::exists(m_inputFile);
|
||||||
if (deploymentSettingsFile.exists())
|
if (inputExists && !AndroidManager::isQtCreatorGenerated(FilePath::fromString(m_inputFile)))
|
||||||
return true; // cmake creates this file for us
|
return true; // use the generated file if it was not generated by qtcreator
|
||||||
|
|
||||||
auto targets = node->data(Android::Constants::AndroidTargets).toStringList();
|
auto targets = node->data(Android::Constants::AndroidTargets).toStringList();
|
||||||
if (targets.isEmpty())
|
if (targets.isEmpty())
|
||||||
return true; // qmake does this job for us
|
return inputExists; // qmake does this job for us
|
||||||
|
|
||||||
|
|
||||||
|
QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(target()->kit());
|
||||||
|
if (!version)
|
||||||
|
return false;
|
||||||
|
|
||||||
QJsonObject deploySettings = Android::AndroidManager::deploymentSettings(target());
|
QJsonObject deploySettings = Android::AndroidManager::deploymentSettings(target());
|
||||||
QJsonObject architectures;
|
QString applicationBinary;
|
||||||
|
if (version->qtVersion() < QtSupport::QtVersionNumber(5, 14, 0)) {
|
||||||
// Copy targets to android build folder
|
QTC_ASSERT(androidAbis.size() == 1, return false);
|
||||||
QString applicationBinary = target()->activeRunConfiguration()->buildTargetInfo().targetFilePath.toFileInfo().fileName();
|
applicationBinary = target()->activeRunConfiguration()->buildTargetInfo().targetFilePath.toString();
|
||||||
for (const auto &abi : androidAbis) {
|
Utils::FilePath androidLibsDir = bc->buildDirectory().pathAppended("android-build/libs").pathAppended(androidAbis.first());
|
||||||
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) {
|
for (const auto &target : targets) {
|
||||||
if (target.endsWith(targetSuffix)) {
|
if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString()))
|
||||||
if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString()))
|
return false;
|
||||||
return false;
|
}
|
||||||
if (abi == "x86") {
|
deploySettings["target-architecture"] = androidAbis.first();
|
||||||
architectures[abi] = "i686-linux-android";
|
} else {
|
||||||
} else if (abi == "x86_64") {
|
applicationBinary = target()->activeRunConfiguration()->buildTargetInfo().targetFilePath.toFileInfo().fileName();
|
||||||
architectures[abi] = "x86_64-linux-android";
|
QJsonObject architectures;
|
||||||
} else if (abi == "arm64-v8a") {
|
|
||||||
architectures[abi] = "aarch64-linux-android";
|
// Copy targets to android build folder
|
||||||
} else {
|
for (const auto &abi : androidAbis) {
|
||||||
architectures[abi] = "arm-linux-androideabi";
|
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["application-binary"] = applicationBinary;
|
||||||
deploySettings["architectures"] = architectures;
|
|
||||||
|
|
||||||
QString extraLibs = node->data(Android::Constants::AndroidExtraLibs).toString();
|
QString extraLibs = node->data(Android::Constants::AndroidExtraLibs).toString();
|
||||||
if (!extraLibs.isEmpty())
|
if (!extraLibs.isEmpty())
|
||||||
@@ -453,7 +462,7 @@ void AndroidBuildApkStep::doRun()
|
|||||||
qmlRootPath = target()->project()->rootProjectDirectory().toString();
|
qmlRootPath = target()->project()->rootProjectDirectory().toString();
|
||||||
deploySettings["qml-root-path"] = qmlRootPath;
|
deploySettings["qml-root-path"] = qmlRootPath;
|
||||||
|
|
||||||
QFile f{deploymentSettingsFile.toString()};
|
QFile f{m_inputFile};
|
||||||
if (!f.open(QIODevice::WriteOnly))
|
if (!f.open(QIODevice::WriteOnly))
|
||||||
return false;
|
return false;
|
||||||
f.write(QJsonDocument{deploySettings}.toJson());
|
f.write(QJsonDocument{deploySettings}.toJson());
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ private:
|
|||||||
QString m_command;
|
QString m_command;
|
||||||
QString m_argumentsPasswordConcealed;
|
QString m_argumentsPasswordConcealed;
|
||||||
bool m_skipBuilding = false;
|
bool m_skipBuilding = false;
|
||||||
|
QString m_inputFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|||||||
@@ -54,17 +54,18 @@
|
|||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/synchronousprocess.h>
|
#include <utils/synchronousprocess.h>
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QDomDocument>
|
||||||
#include <QFileSystemWatcher>
|
#include <QFileSystemWatcher>
|
||||||
|
#include <QJsonDocument>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QDomDocument>
|
|
||||||
#include <QVersionNumber>
|
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
#include <QVersionNumber>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const QLatin1String AndroidManifestName("AndroidManifest.xml");
|
const QLatin1String AndroidManifestName("AndroidManifest.xml");
|
||||||
@@ -76,6 +77,7 @@ namespace {
|
|||||||
const QString activityRegEx("(?<token>launchable-activity: )(.*?)(name=)'(?<target>.*?)'");
|
const QString activityRegEx("(?<token>launchable-activity: )(.*?)(name=)'(?<target>.*?)'");
|
||||||
const QString apkVersionRegEx("(?<token>package: )(.*?)(versionCode=)'(?<target>.*?)'");
|
const QString apkVersionRegEx("(?<token>package: )(.*?)(versionCode=)'(?<target>.*?)'");
|
||||||
const QString versionCodeRegEx("(?<token>versionCode=)(?<version>\\d*)");
|
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)
|
Q_LOGGING_CATEGORY(androidManagerLog, "qtc.android.androidManager", QtWarningMsg)
|
||||||
|
|
||||||
@@ -264,6 +266,18 @@ QStringList AndroidManager::applicationAbis(const Target *target)
|
|||||||
return qt->androidAbis();
|
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)
|
QJsonObject AndroidManager::deploymentSettings(const Target *target)
|
||||||
{
|
{
|
||||||
QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(target->kit());
|
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)
|
if (!tc || tc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID)
|
||||||
return {};
|
return {};
|
||||||
QJsonObject settings;
|
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["qt"] = qt->prefix().toString();
|
||||||
settings["ndk"] = AndroidConfigurations::currentConfig().ndkLocation().toString();
|
settings["ndk"] = AndroidConfigurations::currentConfig().ndkLocation().toString();
|
||||||
settings["sdk"] = AndroidConfigurations::currentConfig().sdkLocation().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["toolchain-prefix"] = "llvm";
|
||||||
settings["tool-prefix"] = "llvm";
|
settings["tool-prefix"] = "llvm";
|
||||||
settings["useLLVM"] = true;
|
settings["useLLVM"] = true;
|
||||||
@@ -286,6 +309,14 @@ QJsonObject AndroidManager::deploymentSettings(const Target *target)
|
|||||||
return settings;
|
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)
|
Utils::FilePath AndroidManager::dirPath(const ProjectExplorer::Target *target)
|
||||||
{
|
{
|
||||||
if (auto *bc = target->activeBuildConfiguration())
|
if (auto *bc = target->activeBuildConfiguration())
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ public:
|
|||||||
static int minimumSDK(const ProjectExplorer::Kit *kit);
|
static int minimumSDK(const ProjectExplorer::Kit *kit);
|
||||||
|
|
||||||
static QStringList applicationAbis(const ProjectExplorer::Target *target);
|
static QStringList applicationAbis(const ProjectExplorer::Target *target);
|
||||||
|
static QString archTriplet(const QString &abi);
|
||||||
|
|
||||||
static Utils::FilePath dirPath(const ProjectExplorer::Target *target);
|
static Utils::FilePath dirPath(const ProjectExplorer::Target *target);
|
||||||
static Utils::FilePath manifestPath(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 SdkToolResult runAaptCommand(const QStringList &args, int timeoutS = 30);
|
||||||
|
|
||||||
static QJsonObject deploymentSettings(const ProjectExplorer::Target *target);
|
static QJsonObject deploymentSettings(const ProjectExplorer::Target *target);
|
||||||
|
static bool isQtCreatorGenerated(const Utils::FilePath &deploymentFile);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static SdkToolResult runCommand(const Utils::CommandLine &command,
|
static SdkToolResult runCommand(const Utils::CommandLine &command,
|
||||||
|
|||||||
Reference in New Issue
Block a user