Android: fix for retrieving the path to deployment file and build dir

The Android deployment file for CMake project was constructed based
on the main project target and thus was always expecting the file
to be under the build folder root path. This makes sure the correct
path to the output path is retrieved.

This practically different problems with running examples when the
main project is a Qt module, for both qmake and cmake.

Fixes: QTCREATORBUG-25793
Change-Id: I5fdedd94c7c4c84c351c28476ca14b0f95f99f22
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Assam Boudjelthia
2021-08-23 21:36:55 +03:00
parent dc71f32483
commit a2b6dba0bc
8 changed files with 77 additions and 32 deletions

View File

@@ -552,13 +552,13 @@ bool AndroidBuildApkStep::init()
} }
m_openPackageLocationForRun = m_openPackageLocation; m_openPackageLocationForRun = m_openPackageLocation;
const FilePath outputDir = AndroidManager::androidBuildDirectory(target());
if (m_buildAAB) { if (m_buildAAB) {
const QString bt = buildType() == BuildConfiguration::Release ? QLatin1String("release") const QString bt = buildType() == BuildConfiguration::Release ? QLatin1String("release")
: QLatin1String("debug"); : QLatin1String("debug");
m_packagePath = buildDirectory() m_packagePath = outputDir.pathAppended(
.pathAppended(Constants::ANDROID_BUILDDIRECTORY) QString("build/outputs/bundle/%1/android-build-%1.aab").arg(bt)).toString();
.pathAppended(QString("build/outputs/bundle/%1/android-build-%1.aab").arg(bt)).toString();
} else { } else {
m_packagePath = AndroidManager::apkPath(target()).toString(); m_packagePath = AndroidManager::apkPath(target()).toString();
} }
@@ -570,8 +570,6 @@ bool AndroidBuildApkStep::init()
command += '/'; command += '/';
command += Utils::HostOsInfo::withExecutableSuffix("androiddeployqt"); command += Utils::HostOsInfo::withExecutableSuffix("androiddeployqt");
QString outputDir = buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY).toString();
m_inputFile = AndroidQtVersion::androidDeploymentSettings(target()).toString(); m_inputFile = AndroidQtVersion::androidDeploymentSettings(target()).toString();
if (m_inputFile.isEmpty()) { if (m_inputFile.isEmpty()) {
qCDebug(buildapkstepLog) << "no input file" << target()->activeBuildKey(); qCDebug(buildapkstepLog) << "no input file" << target()->activeBuildKey();
@@ -588,7 +586,7 @@ bool AndroidBuildApkStep::init()
} }
QStringList arguments = {"--input", m_inputFile, QStringList arguments = {"--input", m_inputFile,
"--output", outputDir, "--output", outputDir.toString(),
"--android-platform", m_buildTargetSdk, "--android-platform", m_buildTargetSdk,
"--jdk", AndroidConfigurations::currentConfig().openJDKLocation().toString()}; "--jdk", AndroidConfigurations::currentConfig().openJDKLocation().toString()};
@@ -647,7 +645,7 @@ void AndroidBuildApkStep::setupOutputFormatter(OutputFormatter *formatter)
sourceDirName = node->data(Constants::AndroidPackageSourceDir).toString(); sourceDirName = node->data(Constants::AndroidPackageSourceDir).toString();
QFileInfo sourceDirInfo(sourceDirName); QFileInfo sourceDirInfo(sourceDirName);
parser->setSourceDirectory(Utils::FilePath::fromString(sourceDirInfo.canonicalFilePath())); parser->setSourceDirectory(Utils::FilePath::fromString(sourceDirInfo.canonicalFilePath()));
parser->setBuildDirectory(buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY)); parser->setBuildDirectory(AndroidManager::androidBuildDirectory(target()));
formatter->addLineParser(parser); formatter->addLineParser(parser);
AbstractProcessStep::setupOutputFormatter(formatter); AbstractProcessStep::setupOutputFormatter(formatter);
} }
@@ -755,10 +753,12 @@ void AndroidBuildApkStep::doRun()
if (!version) if (!version)
return false; return false;
const FilePath buildDir = buildDirectory();
const FilePath androidBuildDir = AndroidManager::androidBuildDirectory(target());
for (const auto &abi : androidAbis) { for (const auto &abi : androidAbis) {
FilePath androidLibsDir = buildDirectory() / "android-build/libs" / abi; FilePath androidLibsDir = androidBuildDir / "libs" / abi;
if (!androidLibsDir.exists()) { if (!androidLibsDir.exists()) {
if (!QDir{buildDirectory().toString()}.mkpath(androidLibsDir.toString())) { if (!QDir{buildDir.toString()}.mkpath(androidLibsDir.toString())) {
const QString error = tr("The Android build folder %1 wasn't found and " const QString error = tr("The Android build folder %1 wasn't found and "
"couldn't be created.").arg(androidLibsDir.toString()); "couldn't be created.").arg(androidLibsDir.toString());
emit addOutput(error, BuildStep::OutputFormat::ErrorMessage); emit addOutput(error, BuildStep::OutputFormat::ErrorMessage);
@@ -770,7 +770,7 @@ void AndroidBuildApkStep::doRun()
// and now it's made directly with ALL target, so this code below ensures // and now it's made directly with ALL target, so this code below ensures
// these versions are not broken. // these versions are not broken.
const QString fileName = QString("lib%1_%2.so").arg(buildKey, abi); const QString fileName = QString("lib%1_%2.so").arg(buildKey, abi);
const FilePath from = buildDirectory() / fileName; const FilePath from = buildDir / fileName;
const FilePath to = androidLibsDir / fileName; const FilePath to = androidLibsDir / fileName;
if (!from.exists() || to.exists()) if (!from.exists() || to.exists())
continue; continue;
@@ -802,7 +802,7 @@ void AndroidBuildApkStep::doRun()
if (!version->supportsMultipleQtAbis()) { if (!version->supportsMultipleQtAbis()) {
QTC_ASSERT(androidAbis.size() == 1, return false); QTC_ASSERT(androidAbis.size() == 1, return false);
applicationBinary = buildSystem()->buildTarget(buildKey).targetFilePath.toString(); applicationBinary = buildSystem()->buildTarget(buildKey).targetFilePath.toString();
FilePath androidLibsDir = buildDirectory() / "android-build/libs" / androidAbis.first(); FilePath androidLibsDir = androidBuildDir / "libs" / androidAbis.first();
for (const auto &target : targets) { for (const auto &target : targets) {
if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString())) if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString()))
return false; return false;
@@ -820,7 +820,7 @@ void AndroidBuildApkStep::doRun()
applicationBinary.remove(0, 3).chop(targetSuffix.size()); applicationBinary.remove(0, 3).chop(targetSuffix.size());
} }
FilePath androidLibsDir = buildDirectory() / "android-build/libs" / abi; FilePath androidLibsDir = androidBuildDir / "libs" / abi;
for (const auto &target : targets) { for (const auto &target : targets) {
if (target.endsWith(targetSuffix)) { if (target.endsWith(targetSuffix)) {
if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString())) if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString()))

View File

@@ -58,7 +58,7 @@ const char ANDROID_MANIFEST_EDITOR_CONTEXT[] = "Android.AndroidManifestEditor.Id
const char ANDROID_KIT_NDK[] = "Android.NDK"; const char ANDROID_KIT_NDK[] = "Android.NDK";
const char ANDROID_KIT_SDK[] = "Android.SDK"; const char ANDROID_KIT_SDK[] = "Android.SDK";
const char ANDROID_BUILDDIRECTORY[] = "android-build"; const char ANDROID_BUILD_DIRECTORY[] = "android-build";
const char JAVA_EDITOR_ID[] = "java.editor"; const char JAVA_EDITOR_ID[] = "java.editor";
const char JLS_SETTINGS_ID[] = "Java::JLSSettingsID"; const char JLS_SETTINGS_ID[] = "Java::JLSSettingsID";
const char JAVA_MIMETYPE[] = "text/x-java"; const char JAVA_MIMETYPE[] = "text/x-java";

View File

@@ -140,11 +140,16 @@ void AndroidDebugSupport::start()
if (qtVersion) if (qtVersion)
solibSearchPath.append(qtVersion->qtSoPaths()); solibSearchPath.append(qtVersion->qtSoPaths());
solibSearchPath.append(uniquePaths(extraLibs)); solibSearchPath.append(uniquePaths(extraLibs));
solibSearchPath.append(runControl()->buildDirectory().toString());
const RunConfiguration *activeRunConfig = target->activeRunConfiguration();
FilePath buildDir;
if (activeRunConfig)
buildDir = activeRunConfig->buildTargetInfo().workingDirectory;
solibSearchPath.append(buildDir.toString());
solibSearchPath.removeDuplicates(); solibSearchPath.removeDuplicates();
setSolibSearchPath(solibSearchPath); setSolibSearchPath(solibSearchPath);
qCDebug(androidDebugSupportLog) << "SoLibSearchPath: "<<solibSearchPath; qCDebug(androidDebugSupportLog) << "SoLibSearchPath: "<<solibSearchPath;
setSymbolFile(runControl()->buildDirectory().pathAppended("app_process")); setSymbolFile(buildDir.pathAppended("app_process"));
setSkipExecutableValidation(true); setSkipExecutableValidation(true);
setUseExtendedRemote(true); setUseExtendedRemote(true);
QString devicePreferredAbi = AndroidManager::apkDevicePreferredAbi(target); QString devicePreferredAbi = AndroidManager::apkDevicePreferredAbi(target);

View File

@@ -188,7 +188,6 @@ bool AndroidDeployQtStep::init()
m_manifestName = AndroidManager::manifestPath(target()); m_manifestName = AndroidManager::manifestPath(target());
m_useAndroiddeployqt = version->qtVersion() >= QtSupport::QtVersionNumber(5, 4, 0); m_useAndroiddeployqt = version->qtVersion() >= QtSupport::QtVersionNumber(5, 4, 0);
if (m_useAndroiddeployqt) { if (m_useAndroiddeployqt) {
const QString buildKey = target()->activeBuildKey(); const QString buildKey = target()->activeBuildKey();
const ProjectNode *node = target()->project()->findNodeForBuildKey(buildKey); const ProjectNode *node = target()->project()->findNodeForBuildKey(buildKey);
@@ -216,7 +215,7 @@ bool AndroidDeployQtStep::init()
} }
m_command = m_command.pathAppended(HostOsInfo::withExecutableSuffix("androiddeployqt")); m_command = m_command.pathAppended(HostOsInfo::withExecutableSuffix("androiddeployqt"));
m_workingDirectory = bc->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY); m_workingDirectory = AndroidManager::androidBuildDirectory(target());
m_androiddeployqtArgs.addArgs({"--verbose", m_androiddeployqtArgs.addArgs({"--verbose",
"--output", m_workingDirectory.toString(), "--output", m_workingDirectory.toString(),
@@ -237,7 +236,7 @@ bool AndroidDeployQtStep::init()
m_uninstallPreviousPackageRun = true; m_uninstallPreviousPackageRun = true;
m_command = AndroidConfigurations::currentConfig().adbToolPath(); m_command = AndroidConfigurations::currentConfig().adbToolPath();
m_apkPath = AndroidManager::apkPath(target()); m_apkPath = AndroidManager::apkPath(target());
m_workingDirectory = bc ? bc->buildDirectory() : FilePath(); m_workingDirectory = bc ? AndroidManager::buildDirectory(target()): FilePath();
} }
m_environment = bc ? bc->environment() : Utils::Environment(); m_environment = bc ? bc->environment() : Utils::Environment();
@@ -444,9 +443,8 @@ bool AndroidDeployQtStep::runImpl()
void AndroidDeployQtStep::gatherFilesToPull() void AndroidDeployQtStep::gatherFilesToPull()
{ {
m_filesToPull.clear(); m_filesToPull.clear();
BuildConfiguration *bc = target()->activeBuildConfiguration(); QString buildDir = AndroidManager::buildDirectory(target()).toString();
QString buildDir = bc ? bc->buildDirectory().toString() : QString(); if (!buildDir.endsWith("/")) {
if (bc && !buildDir.endsWith("/")) {
buildDir += "/"; buildDir += "/";
} }

View File

@@ -47,6 +47,7 @@
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <projectexplorer/buildsystem.h>
#include <qtsupport/qtkitinformation.h> #include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h> #include <qtsupport/qtsupportconstants.h>
@@ -244,8 +245,18 @@ bool AndroidManager::isQtCreatorGenerated(const FilePath &deploymentFile)
FilePath AndroidManager::dirPath(const Target *target) FilePath AndroidManager::dirPath(const Target *target)
{ {
if (auto *bc = target->activeBuildConfiguration()) return androidBuildDirectory(target);
return bc->buildDirectory() / Constants::ANDROID_BUILDDIRECTORY; }
FilePath AndroidManager::androidBuildDirectory(const Target *target)
{
return buildDirectory(target) / Constants::ANDROID_BUILD_DIRECTORY;
}
FilePath AndroidManager::buildDirectory(const Target *target)
{
if (const BuildSystem *bs = target->buildSystem())
return bs->buildTarget(target->activeBuildKey()).workingDirectory;
return {}; return {};
} }
@@ -266,7 +277,7 @@ FilePath AndroidManager::apkPath(const Target *target)
else else
apkPath += QLatin1String("debug.apk"); apkPath += QLatin1String("debug.apk");
return dirPath(target) / apkPath; return androidBuildDirectory(target) / apkPath;
} }
bool AndroidManager::matchedAbis(const QStringList &deviceAbis, const QStringList &appAbis) bool AndroidManager::matchedAbis(const QStringList &deviceAbis, const QStringList &appAbis)
@@ -341,7 +352,7 @@ FilePath AndroidManager::manifestPath(const Target *target)
QVariant manifest = target->namedSettings(AndroidManifestName); QVariant manifest = target->namedSettings(AndroidManifestName);
if (manifest.isValid()) if (manifest.isValid())
return manifest.value<FilePath>(); return manifest.value<FilePath>();
return dirPath(target).pathAppended(AndroidManifestName); return androidBuildDirectory(target).pathAppended(AndroidManifestName);
} }
void AndroidManager::setManifestPath(Target *target, const FilePath &path) void AndroidManager::setManifestPath(Target *target, const FilePath &path)
@@ -373,7 +384,7 @@ static QString preferredAbi(const QStringList &appAbis, const Target *target)
QString AndroidManager::apkDevicePreferredAbi(const Target *target) QString AndroidManager::apkDevicePreferredAbi(const Target *target)
{ {
auto libsPath = dirPath(target).pathAppended("libs"); auto libsPath = androidBuildDirectory(target).pathAppended("libs");
if (!libsPath.exists()) { if (!libsPath.exists()) {
if (const ProjectNode *node = currentProjectNode(target)) if (const ProjectNode *node = currentProjectNode(target))
return preferredAbi(node->data(Android::Constants::ANDROID_ABIS).toStringList(), return preferredAbi(node->data(Android::Constants::ANDROID_ABIS).toStringList(),

View File

@@ -93,7 +93,10 @@ public:
static QStringList applicationAbis(const ProjectExplorer::Target *target); static QStringList applicationAbis(const ProjectExplorer::Target *target);
static QString archTriplet(const QString &abi); static QString archTriplet(const QString &abi);
// TODO: remove this on 6.0 branch, kept here for binary compatibility for 5.0 release.
static Utils::FilePath dirPath(const ProjectExplorer::Target *target); static Utils::FilePath dirPath(const ProjectExplorer::Target *target);
static Utils::FilePath androidBuildDirectory(const ProjectExplorer::Target *target);
static Utils::FilePath buildDirectory(const ProjectExplorer::Target *target);
static Utils::FilePath manifestPath(const ProjectExplorer::Target *target); static Utils::FilePath manifestPath(const ProjectExplorer::Target *target);
static void setManifestPath(ProjectExplorer::Target *target, const Utils::FilePath &path); static void setManifestPath(ProjectExplorer::Target *target, const Utils::FilePath &path);
static Utils::FilePath manifestSourcePath(const ProjectExplorer::Target *target); static Utils::FilePath manifestSourcePath(const ProjectExplorer::Target *target);

View File

@@ -38,6 +38,7 @@
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <projectexplorer/taskhub.h> #include <projectexplorer/taskhub.h>
#include <projectexplorer/toolchain.h> #include <projectexplorer/toolchain.h>
#include <projectexplorer/buildsystem.h>
#include <qtsupport/baseqtversion.h> #include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitinformation.h> #include <qtsupport/qtkitinformation.h>
@@ -67,6 +68,9 @@ public:
QString nativeAndroidBuildPath() const; QString nativeAndroidBuildPath() const;
Utils::FilePath androidBuildDirectory() const;
Utils::FilePath buildDirectory() const;
private: private:
bool init() final; bool init() final;
void setupOutputFormatter(OutputFormatter *formatter) final; void setupOutputFormatter(OutputFormatter *formatter) final;
@@ -103,6 +107,8 @@ bool AndroidPackageInstallationStep::init()
cmd.addArgs(outerQuoted + " install", CommandLine::Raw); cmd.addArgs(outerQuoted + " install", CommandLine::Raw);
processParameters()->setCommandLine(cmd); processParameters()->setCommandLine(cmd);
// This is useful when running an example target from a Qt module project.
processParameters()->setWorkingDirectory(buildDirectory());
m_androidDirsToClean.clear(); m_androidDirsToClean.clear();
// don't remove gradle's cache, it takes ages to rebuild it. // don't remove gradle's cache, it takes ages to rebuild it.
@@ -114,7 +120,7 @@ bool AndroidPackageInstallationStep::init()
QString AndroidPackageInstallationStep::nativeAndroidBuildPath() const QString AndroidPackageInstallationStep::nativeAndroidBuildPath() const
{ {
QString buildPath = buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY).toString(); QString buildPath = androidBuildDirectory().toString();
if (HostOsInfo::isWindowsHost()) if (HostOsInfo::isWindowsHost())
if (buildEnvironment().searchInPath("sh.exe").isEmpty()) if (buildEnvironment().searchInPath("sh.exe").isEmpty())
buildPath = QDir::toNativeSeparators(buildPath); buildPath = QDir::toNativeSeparators(buildPath);
@@ -122,6 +128,18 @@ QString AndroidPackageInstallationStep::nativeAndroidBuildPath() const
return buildPath; return buildPath;
} }
FilePath AndroidPackageInstallationStep::androidBuildDirectory() const
{
return buildDirectory() / Constants::ANDROID_BUILD_DIRECTORY;
}
FilePath AndroidPackageInstallationStep::buildDirectory() const
{
if (const BuildSystem *bs = buildSystem())
return buildSystem()->buildTarget(target()->activeBuildKey()).workingDirectory;
return {};
}
void AndroidPackageInstallationStep::setupOutputFormatter(OutputFormatter *formatter) void AndroidPackageInstallationStep::setupOutputFormatter(OutputFormatter *formatter)
{ {
formatter->addLineParser(new GnuMakeParser); formatter->addLineParser(new GnuMakeParser);

View File

@@ -42,6 +42,8 @@
#include <projectexplorer/kit.h> #include <projectexplorer/kit.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/projecttree.h> #include <projectexplorer/projecttree.h>
#include <projectexplorer/buildsystem.h>
#include <cmakeprojectmanager/cmakeprojectconstants.h>
#include <proparser/profileevaluator.h> #include <proparser/profileevaluator.h>
@@ -172,19 +174,27 @@ int AndroidQtVersion::minimumNDK() const
Utils::FilePath AndroidQtVersion::androidDeploymentSettings(const Target *target) Utils::FilePath AndroidQtVersion::androidDeploymentSettings(const Target *target)
{ {
// Try to fetch the file name from node data as provided by qmake and Qbs // Try to fetch the file name from node data as provided by qmake and Qbs
const QString buildKey = target->activeBuildKey(); QString buildKey = target->activeBuildKey();
const ProjectNode *node = target->project()->findNodeForBuildKey(buildKey); const ProjectNode *node = target->project()->findNodeForBuildKey(buildKey);
if (node) { if (node) {
const QString nameFromData = node->data(Constants::AndroidDeploySettingsFile).toString(); const QString nameFromData = node->data(Constants::AndroidDeploySettingsFile).toString();
if (!nameFromData.isEmpty()) if (!nameFromData.isEmpty())
return Utils::FilePath::fromUserInput(nameFromData); return Utils::FilePath::fromUserInput(nameFromData);
} }
// If unavailable, construct the name by ourselves (CMake) // If unavailable, construct the name by ourselves (CMake)
const BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(target->kit()); const BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(target->kit());
const bool isQt6 = qt && qt->qtVersion() >= QtSupport::QtVersionNumber{6, 0, 0}; const bool isQt5 = qt && qt->qtVersion() < QtSupport::QtVersionNumber{6, 0, 0};
return target->activeBuildConfiguration()->buildDirectory().pathAppended( const Core::Context cmakeCtx = Core::Context(CMakeProjectManager::Constants::CMAKE_PROJECT_ID);
isQt6 ? QString::fromLatin1("android-%1-deployment-settings.json").arg(buildKey) const bool isCmakeProject = (target->project()->projectContext() == cmakeCtx);
: QLatin1String("android_deployment_settings.json")); const BuildSystem *bs = target->buildSystem();
if (!bs)
return {};
const BuildTargetInfo buildTarget = bs->buildTarget(buildKey);
return buildTarget.workingDirectory.pathAppended((isQt5 && isCmakeProject)
? QLatin1String("android_deployment_settings.json")
: QString::fromLatin1("android-%1-deployment-settings.json")
.arg(buildTarget.displayName));
} }
void AndroidQtVersion::parseMkSpec(ProFileEvaluator *evaluator) const void AndroidQtVersion::parseMkSpec(ProFileEvaluator *evaluator) const