diff options
Diffstat (limited to 'src/plugins')
| -rw-r--r-- | src/plugins/android/androidbuildapkstep.cpp | 74 | ||||
| -rw-r--r-- | src/plugins/android/androidbuildapkstep.h | 3 | ||||
| -rw-r--r-- | src/plugins/android/androiddeployqtstep.cpp | 84 |
3 files changed, 161 insertions, 0 deletions
diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index 6cbe6367713..0ed1c12516a 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -1045,6 +1045,13 @@ QtTaskTree::GroupItem AndroidBuildApkStep::runRecipe() Task::Warning); return SetupResult::StopWithSuccess; } + + if (!needsApkRegeneration()) { + emit addOutput(Tr::tr("No changes detected, skipping APK regeneration."), + OutputFormat::NormalMessage); + return SetupResult::StopWithSuccess; + } + if (setupHelper()) return SetupResult::Continue; reportWarningOrError(Tr::tr("Cannot set up \"%1\", not building an APK.") @@ -1052,6 +1059,7 @@ QtTaskTree::GroupItem AndroidBuildApkStep::runRecipe() return SetupResult::StopWithError; }; const auto onDone = [this] { + updateBuildTimestamp(); if (m_openPackageLocationForRun) QTimer::singleShot(0, this, &AndroidBuildApkStep::showInGraphicalShell); }; @@ -1064,6 +1072,72 @@ QtTaskTree::GroupItem AndroidBuildApkStep::runRecipe() return root; } +bool AndroidBuildApkStep::needsApkRegeneration() +{ + const FilePath androidBuildDir = androidBuildDirectory(buildConfiguration()); + const FilePath apkOutputDir = androidBuildDir / "build/outputs/apk"; + if (!apkOutputDir.exists()) { + emit addOutput(Tr::tr("APK output directory does not exist, regenerating APK."), + OutputFormat::NormalMessage); + return true; + } + + const FilePath timestampFile = androidBuildDir / "AndroidBuildTimestamp"; + if (!m_lastBuildTime.isValid()) { + if (timestampFile.exists()) { + m_lastBuildTime = timestampFile.lastModified(); + qCDebug(buildapkstepLog) << "Loaded build timestamp from file:" << m_lastBuildTime; + } else { + emit addOutput(Tr::tr("First build in session, regenerating APK."), + OutputFormat::NormalMessage); + return true; + } + } + + if (m_inputFile.exists() && m_inputFile.lastModified() > m_lastBuildTime) { + emit addOutput(Tr::tr("Deployment settings changed since last build, regenerating APK."), + OutputFormat::NormalMessage); + return true; + } + + BuildSystem *bs = buildSystem(); + const QStringList androidAbis = bs->property(Constants::AndroidAbis).toStringList(); + for (const QString &abi : androidAbis) { + const FilePath libsDir = androidBuildDir / "libs" / abi; + if (libsDir.exists()) { + const FilePaths files = libsDir.dirEntries(QDir::Files); + for (const FilePath &file : files) { + if (file.lastModified() > m_lastBuildTime) { + emit addOutput(Tr::tr("Library %1 changed since last build, regenerating APK.") + .arg(file.fileName()), + OutputFormat::NormalMessage); + return true; + } + } + } + } + + const QString buildKey = buildConfiguration()->activeBuildKey(); + const ProjectNode *node = project()->findNodeForBuildKey(buildKey); + if (node) { + const FilePath apk = FilePath::fromString(node->data(Constants::AndroidApk).toString()); + if (!apk.isEmpty() && apk.exists() && apk.lastModified() > m_lastBuildTime) { + emit addOutput(Tr::tr("Application binary changed since last build, regenerating APK."), + OutputFormat::NormalMessage); + return true; + } + } + + return false; +} + +void AndroidBuildApkStep::updateBuildTimestamp() +{ + m_lastBuildTime = QDateTime::currentDateTime(); + const FilePath timestampFile = androidBuildDirectory(buildConfiguration()) / "AndroidBuildTimestamp"; + timestampFile.writeFileContents(QByteArray()); +} + void AndroidBuildApkStep::reportWarningOrError(const QString &message, Task::TaskType type) { qCDebug(buildapkstepLog) << message; diff --git a/src/plugins/android/androidbuildapkstep.h b/src/plugins/android/androidbuildapkstep.h index 3d3a6e025b5..34b08607cb7 100644 --- a/src/plugins/android/androidbuildapkstep.h +++ b/src/plugins/android/androidbuildapkstep.h @@ -65,6 +65,8 @@ private: void reportWarningOrError(const QString &message, ProjectExplorer::Task::TaskType type); void updateBuildToolsVersionInJsonFile(); + bool needsApkRegeneration(); + void updateBuildTimestamp(); bool m_signPackage = false; bool m_openPackageLocationForRun = false; @@ -81,6 +83,7 @@ private: ProjectExplorer::ProcessParameters m_concealedParams; bool m_skipBuilding = false; Utils::FilePath m_inputFile; + QDateTime m_lastBuildTime; }; void setupAndroidBuildApkStep(); diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index cccc75347c3..04ca2d76606 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -40,6 +40,7 @@ #include <utils/qtcassert.h> #include <utils/qtcprocess.h> +#include <QDateTime> #include <QLoggingCategory> #include <QMessageBox> #include <QPushButton> @@ -114,6 +115,8 @@ private: void reportWarningOrError(const QString &message, Task::TaskType type); void setInstallApkError(const QString &details); + bool needsPackageRegeneration(); + void updateDeploymentTimestamp(); QString m_serialNumber; QString m_avdName; @@ -128,6 +131,7 @@ private: Environment m_environment; Task m_installApkError; QSingleTaskTreeRunner m_taskTreeRunner; + QDateTime m_lastDeploymentTime; }; AndroidDeployQtStep::AndroidDeployQtStep(BuildStepList *parent, Id id) @@ -294,6 +298,79 @@ bool AndroidDeployQtStep::init() return true; } +bool AndroidDeployQtStep::needsPackageRegeneration() +{ + const FilePath jsonFile = AndroidQtVersion::androidDeploymentSettings(buildConfiguration()); + if (!jsonFile.exists()) { + emit addOutput(Tr::tr("Deployment settings JSON file does not exist, regenerating package."), + OutputFormat::NormalMessage); + return true; + } + + const FilePath androidBuildDir = androidBuildDirectory(buildConfiguration()); + const FilePath apkOutputDir = androidBuildDir / "build/outputs/apk"; + if (!apkOutputDir.exists()) { + emit addOutput(Tr::tr("APK output directory does not exist, regenerating package."), + OutputFormat::NormalMessage); + return true; + } + + const FilePath timestampFile = androidBuildDir / "AndroidDeployTimestamp"; + if (!m_lastDeploymentTime.isValid()) { + if (timestampFile.exists()) { + m_lastDeploymentTime = timestampFile.lastModified(); + } else { + emit addOutput(Tr::tr("First deployment in session, regenerating package."), + OutputFormat::NormalMessage); + return true; + } + } + + const BuildSystem *bs = buildSystem(); + const QString buildKey = buildConfiguration()->activeBuildKey(); + + if (jsonFile.lastModified() > m_lastDeploymentTime) { + emit addOutput(Tr::tr("Deployment settings changed since last deploy, regenerating package."), + OutputFormat::NormalMessage); + return true; + } + + const ProjectNode *node = project()->findNodeForBuildKey(buildKey); + if (node) { + const FilePath apk = FilePath::fromString(node->data(Constants::AndroidApk).toString()); + if (!apk.isEmpty() && apk.exists() && apk.lastModified() > m_lastDeploymentTime) { + emit addOutput(Tr::tr("Application binary changed since last deploy, regenerating package."), + OutputFormat::NormalMessage); + return true; + } + } + + const QStringList androidAbis = bs->property(Constants::AndroidAbis).toStringList(); + for (const QString &abi : androidAbis) { + const FilePath libsDir = androidBuildDir / "libs" / abi; + if (libsDir.exists()) { + const FilePaths files = libsDir.dirEntries(QDir::Files); + for (const FilePath &file : files) { + if (file.lastModified() > m_lastDeploymentTime) { + emit addOutput(Tr::tr("Library %1 changed since last deploy, regenerating package.") + .arg(file.fileName()), + OutputFormat::NormalMessage); + return true; + } + } + } + } + + return false; +} + +void AndroidDeployQtStep::updateDeploymentTimestamp() +{ + m_lastDeploymentTime = QDateTime::currentDateTime(); + const FilePath timestampFile = androidBuildDirectory(buildConfiguration()) / "AndroidDeployTimestamp"; + timestampFile.writeFileContents(QByteArray()); +} + GroupItem AndroidDeployQtStep::runRecipe() { const Storage<QString> serialNumberStorage; @@ -357,6 +434,12 @@ Group AndroidDeployQtStep::deployRecipe() }; const auto onInstallSetup = [this, storage](Process &process) { + if (!needsPackageRegeneration()) { + emit addOutput(Tr::tr("No changes detected, skipping package regeneration."), + OutputFormat::NormalMessage); + return SetupResult::StopWithSuccess; + } + CommandLine cmd(m_command); if (m_apkPath.isEmpty()) { cmd.addArgs(m_androiddeployqtArgs.arguments(), CommandLine::Raw); @@ -397,6 +480,7 @@ Group AndroidDeployQtStep::deployRecipe() if (exitStatus == QProcess::NormalExit && exitCode == 0) { emit addOutput(Tr::tr("The process \"%1\" exited normally.").arg(m_command.toUserOutput()), OutputFormat::NormalMessage); + updateDeploymentTimestamp(); } else if (exitStatus == QProcess::NormalExit) { const QString error = Tr::tr("The process \"%1\" exited with code %2.") .arg(m_command.toUserOutput(), QString::number(exitCode)); |
