Android: Move some generic apk build step code to base

Change-Id: Id11e5d684e2e1003178d06b4421ec34df334fca2
Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io>
This commit is contained in:
hjk
2018-06-13 13:51:41 +02:00
parent 172d6184a5
commit d4f5b74df9
4 changed files with 112 additions and 152 deletions

View File

@@ -59,6 +59,8 @@
#include <memory> #include <memory>
using namespace ProjectExplorer;
namespace Android { namespace Android {
using namespace Internal; using namespace Internal;
@@ -68,6 +70,20 @@ const char BuildTargetSdkKey[] = "BuildTargetSdk";
const char VerboseOutputKey[] = "VerboseOutput"; const char VerboseOutputKey[] = "VerboseOutput";
const char UseMinistroKey[] = "UseMinistro"; const char UseMinistroKey[] = "UseMinistro";
static void setupProcessParameters(ProcessParameters *pp,
BuildConfiguration *bc,
const QStringList &arguments,
const QString &command)
{
pp->setMacroExpander(bc->macroExpander());
pp->setWorkingDirectory(bc->buildDirectory().toString());
Utils::Environment env = bc->environment();
pp->setEnvironment(env);
pp->setCommand(command);
pp->setArguments(Utils::QtcProcess::joinArgs(arguments));
pp->resolveAll();
}
class PasswordInputDialog : public QDialog class PasswordInputDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
@@ -158,10 +174,77 @@ bool AndroidBuildApkStep::init(QList<const BuildStep *> &earlierSteps)
m_openPackageLocationForRun = m_openPackageLocation; m_openPackageLocationForRun = m_openPackageLocation;
m_apkPath = qtSupport->apkPath(target()).toString(); m_apkPath = qtSupport->apkPath(target()).toString();
bool result = AbstractProcessStep::init(earlierSteps); if (!AbstractProcessStep::init(earlierSteps))
if (!result)
return false; return false;
QString command = version->qmakeProperty("QT_HOST_BINS");
if (!command.endsWith('/'))
command += '/';
command += "androiddeployqt";
if (Utils::HostOsInfo::isWindowsHost())
command += ".exe";
QString outputDir = bc->buildDirectory().appendPath(Constants::ANDROID_BUILDDIRECTORY).toString();
QString inputFile = AndroidManager::androidQtSupport(target())
->targetDataItem(Constants::AndroidDeploySettingsFile, target());
if (inputFile.isEmpty()) {
m_skipBuilding = true;
return true;
}
QString buildTargetSdk = AndroidManager::buildTargetSDK(target());
if (buildTargetSdk.isEmpty()) {
emit addOutput(tr("Android build SDK not defined. Check Android settings."),
OutputFormat::Stderr);
return false;
}
QStringList arguments = {"--input", inputFile,
"--output", outputDir,
"--android-platform", AndroidManager::buildTargetSDK(target()),
"--jdk", AndroidConfigurations::currentConfig().openJDKLocation().toString()};
if (m_verbose)
arguments << "--verbose";
arguments << "--gradle";
if (m_useMinistro)
arguments << "--deployment" << "ministro";
QStringList argumentsPasswordConcealed = arguments;
if (m_signPackage) {
arguments << "--sign" << m_keystorePath.toString() << m_certificateAlias
<< "--storepass" << m_keystorePasswd;
argumentsPasswordConcealed << "--sign" << "******"
<< "--storepass" << "******";
if (!m_certificatePasswd.isEmpty()) {
arguments << "--keypass" << m_certificatePasswd;
argumentsPasswordConcealed << "--keypass" << "******";
}
}
// Must be the last option, otherwise androiddeployqt might use the other
// params (e.g. --sign) to choose not to add gdbserver
if (version->qtVersion() >= QtSupport::QtVersionNumber(5, 6, 0)) {
if (m_addDebugger || bc->buildType() == ProjectExplorer::BuildConfiguration::Debug)
arguments << "--gdbserver";
else
arguments << "--no-gdbserver";
}
ProjectExplorer::ProcessParameters *pp = processParameters();
setupProcessParameters(pp, bc, arguments, command);
// Generate arguments with keystore password concealed
ProjectExplorer::ProcessParameters pp2;
setupProcessParameters(&pp2, bc, argumentsPasswordConcealed, command);
m_command = pp2.effectiveCommand();
m_argumentsPasswordConcealed = pp2.prettyArguments();
return true; return true;
} }
@@ -226,6 +309,24 @@ bool AndroidBuildApkStep::verifyCertificatePassword()
return success; return success;
} }
void AndroidBuildApkStep::run(QFutureInterface<bool> &fi)
{
if (m_skipBuilding) {
emit addOutput(tr("No application .pro file found, not building an APK."), BuildStep::OutputFormat::ErrorMessage);
reportRunResult(fi, true);
return;
}
AbstractProcessStep::run(fi);
}
void AndroidBuildApkStep::processStarted()
{
emit addOutput(tr("Starting: \"%1\" %2")
.arg(QDir::toNativeSeparators(m_command),
m_argumentsPasswordConcealed),
BuildStep::OutputFormat::NormalMessage);
}
bool AndroidBuildApkStep::fromMap(const QVariantMap &map) bool AndroidBuildApkStep::fromMap(const QVariantMap &map)
{ {
m_keystorePath = Utils::FileName::fromString(map.value(KeystoreLocationKey).toString()); m_keystorePath = Utils::FileName::fromString(map.value(KeystoreLocationKey).toString());

View File

@@ -72,17 +72,19 @@ public:
QString buildTargetSdk() const; QString buildTargetSdk() const;
void setBuildTargetSdk(const QString &sdk); void setBuildTargetSdk(const QString &sdk);
protected: private:
Q_INVOKABLE void showInGraphicalShell(); Q_INVOKABLE void showInGraphicalShell();
bool init(QList<const BuildStep *> &earlierSteps) override; bool init(QList<const BuildStep *> &earlierSteps) override;
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override; ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
bool immutable() const override { return true; } bool immutable() const override { return true; }
void processStarted() override;
void processFinished(int exitCode, QProcess::ExitStatus status) override; void processFinished(int exitCode, QProcess::ExitStatus status) override;
bool verifyKeystorePassword(); bool verifyKeystorePassword();
bool verifyCertificatePassword(); bool verifyCertificatePassword();
protected: void run(QFutureInterface<bool> &fi) override;
bool m_signPackage = false; bool m_signPackage = false;
bool m_verbose = false; bool m_verbose = false;
bool m_useMinistro = false; bool m_useMinistro = false;
@@ -96,6 +98,10 @@ protected:
QString m_certificateAlias; QString m_certificateAlias;
QString m_certificatePasswd; QString m_certificatePasswd;
QString m_apkPath; QString m_apkPath;
QString m_command;
QString m_argumentsPasswordConcealed;
bool m_skipBuilding = false;
}; };
} // namespace Android } // namespace Android

View File

@@ -27,22 +27,12 @@
#include "qmakeandroidbuildapkstep.h" #include "qmakeandroidbuildapkstep.h"
#include "qmakeandroidbuildapkwidget.h" #include "qmakeandroidbuildapkwidget.h"
#include <android/androidconfigurations.h>
#include <android/androidconstants.h> #include <android/androidconstants.h>
#include <android/androidmanager.h>
#include <android/androidqtsupport.h>
#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/target.h>
#include <qtsupport/qtkitinformation.h>
#include <qmakeprojectmanager/qmakeprojectmanagerconstants.h> #include <qmakeprojectmanager/qmakeprojectmanagerconstants.h>
#include <utils/qtcprocess.h>
using namespace Android; using namespace Android;
namespace QmakeAndroidSupport { namespace QmakeAndroidSupport {
@@ -70,134 +60,10 @@ QmakeAndroidBuildApkStep::QmakeAndroidBuildApkStep(ProjectExplorer::BuildStepLis
{ {
} }
bool QmakeAndroidBuildApkStep::init(QList<const BuildStep *> &earlierSteps)
{
if (!AndroidBuildApkStep::init(earlierSteps))
return false;
QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit());
if (!version)
return false;
QString command = version->qmakeProperty("QT_HOST_BINS");
if (!command.endsWith('/'))
command += '/';
command += "androiddeployqt";
if (Utils::HostOsInfo::isWindowsHost())
command += ".exe";
ProjectExplorer::BuildConfiguration *bc = buildConfiguration();
QString outputDir = bc->buildDirectory().appendPath(Constants::ANDROID_BUILDDIRECTORY).toString();
QString inputFile = AndroidManager::androidQtSupport(target())
->targetDataItem(Constants::AndroidDeploySettingsFile, target());
if (inputFile.isEmpty()) {
m_skipBuilding = true;
return true;
}
QString buildTargetSdk = AndroidManager::buildTargetSDK(target());
if (buildTargetSdk.isEmpty()) {
emit addOutput(tr("Android build SDK not defined. Check Android settings."),
OutputFormat::Stderr);
return false;
}
QStringList arguments = {"--input", inputFile,
"--output", outputDir,
"--android-platform", AndroidManager::buildTargetSDK(target()),
"--jdk", AndroidConfigurations::currentConfig().openJDKLocation().toString()};
if (m_verbose)
arguments << "--verbose";
arguments << "--gradle";
if (m_useMinistro)
arguments << "--deployment" << "ministro";
QStringList argumentsPasswordConcealed = arguments;
if (m_signPackage) {
arguments << "--sign" << m_keystorePath.toString() << m_certificateAlias
<< "--storepass" << m_keystorePasswd;
argumentsPasswordConcealed << "--sign" << "******"
<< "--storepass" << "******";
if (!m_certificatePasswd.isEmpty()) {
arguments << "--keypass" << m_certificatePasswd;
argumentsPasswordConcealed << "--keypass" << "******";
}
}
// Must be the last option, otherwise androiddeployqt might use the other
// params (e.g. --sign) to choose not to add gdbserver
if (version->qtVersion() >= QtSupport::QtVersionNumber(5, 6, 0)) {
if (m_addDebugger || bc->buildType() == ProjectExplorer::BuildConfiguration::Debug)
arguments << "--gdbserver";
else
arguments << "--no-gdbserver";
}
ProjectExplorer::ProcessParameters *pp = processParameters();
setupProcessParameters(pp, bc, arguments, command);
// Generate arguments with keystore password concealed
ProjectExplorer::ProcessParameters pp2;
setupProcessParameters(&pp2, bc, argumentsPasswordConcealed, command);
m_command = pp2.effectiveCommand();
m_argumentsPasswordConcealed = pp2.prettyArguments();
return true;
}
void QmakeAndroidBuildApkStep::run(QFutureInterface<bool> &fi)
{
if (m_skipBuilding) {
emit addOutput(tr("No application .pro file found, not building an APK."), BuildStep::OutputFormat::ErrorMessage);
reportRunResult(fi, true);
return;
}
AndroidBuildApkStep::run(fi);
}
void QmakeAndroidBuildApkStep::setupProcessParameters(ProjectExplorer::ProcessParameters *pp,
ProjectExplorer::BuildConfiguration *bc,
const QStringList &arguments,
const QString &command)
{
pp->setMacroExpander(bc->macroExpander());
pp->setWorkingDirectory(bc->buildDirectory().toString());
Utils::Environment env = bc->environment();
pp->setEnvironment(env);
pp->setCommand(command);
pp->setArguments(Utils::QtcProcess::joinArgs(arguments));
pp->resolveAll();
}
void QmakeAndroidBuildApkStep::processStarted()
{
emit addOutput(tr("Starting: \"%1\" %2")
.arg(QDir::toNativeSeparators(m_command),
m_argumentsPasswordConcealed),
BuildStep::OutputFormat::NormalMessage);
}
ProjectExplorer::BuildStepConfigWidget *QmakeAndroidBuildApkStep::createConfigWidget() ProjectExplorer::BuildStepConfigWidget *QmakeAndroidBuildApkStep::createConfigWidget()
{ {
return new QmakeAndroidBuildApkWidget(this); return new QmakeAndroidBuildApkWidget(this);
} }
bool QmakeAndroidBuildApkStep::fromMap(const QVariantMap &map)
{
return AndroidBuildApkStep::fromMap(map);
}
QVariantMap QmakeAndroidBuildApkStep::toMap() const
{
QVariantMap map = AndroidBuildApkStep::toMap();
return map;
}
} // namespace Internal } // namespace Internal
} // namespace QmakeAndroidSupport } // namespace QmakeAndroidSupport

View File

@@ -44,20 +44,7 @@ public:
QmakeAndroidBuildApkStep(ProjectExplorer::BuildStepList *bc); QmakeAndroidBuildApkStep(ProjectExplorer::BuildStepList *bc);
protected: protected:
bool init(QList<const BuildStep *> &earlierSteps) override;
void run(QFutureInterface<bool> &fi) override;
void processStarted() override;
ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override; ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
bool fromMap(const QVariantMap &map) override;
QVariantMap toMap() const override;
private:
void setupProcessParameters(ProjectExplorer::ProcessParameters *pp,
ProjectExplorer::BuildConfiguration *bc,
const QStringList &arguments, const QString &command);
QString m_command;
QString m_argumentsPasswordConcealed;
bool m_skipBuilding = false;
}; };
} // namespace Internal } // namespace Internal