diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index c80f56d5ed4..b5ad731b669 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -149,7 +149,7 @@ QString AndroidManager::activityName(ProjectExplorer::Target *target) int AndroidManager::minimumSDK(ProjectExplorer::Target *target) { QDomDocument doc; - if (!openManifest(target, doc)) + if (!openXmlFile(doc, AndroidManager::manifestSourcePath(target))) return 0; QDomElement manifestElem = doc.documentElement(); QDomElement usesSdk = manifestElem.firstChildElement(QLatin1String("uses-sdk")); @@ -192,7 +192,18 @@ QString AndroidManager::targetArch(ProjectExplorer::Target *target) Utils::FileName AndroidManager::dirPath(ProjectExplorer::Target *target) { - return target->activeBuildConfiguration()->buildDirectory().appendPath(QLatin1String(Constants::ANDROID_BUILDDIRECTORY)); + if (target->activeBuildConfiguration()) + return target->activeBuildConfiguration()->buildDirectory().appendPath(QLatin1String(Constants::ANDROID_BUILDDIRECTORY)); + return Utils::FileName(); +} + +Utils::FileName AndroidManager::manifestSourcePath(ProjectExplorer::Target *target) +{ + AndroidQtSupport *androidQtSupport = AndroidManager::androidQtSupport(target); + Utils::FileName source = androidQtSupport->manifestSourcePath(target); + if (!source.isEmpty()) + return source; + return manifestPath(target); } Utils::FileName AndroidManager::manifestPath(ProjectExplorer::Target *target) diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index 17b11f90136..acb81dfafdc 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -77,6 +77,7 @@ public: static Utils::FileName dirPath(ProjectExplorer::Target *target); static Utils::FileName manifestPath(ProjectExplorer::Target *target); + static Utils::FileName manifestSourcePath(ProjectExplorer::Target *target); static Utils::FileName libsPath(ProjectExplorer::Target *target); static Utils::FileName defaultPropertiesPath(ProjectExplorer::Target *target); diff --git a/src/plugins/android/androidmanifestdocument.cpp b/src/plugins/android/androidmanifestdocument.cpp index 64696959d85..cce32f2edfd 100644 --- a/src/plugins/android/androidmanifestdocument.cpp +++ b/src/plugins/android/androidmanifestdocument.cpp @@ -51,7 +51,9 @@ AndroidManifestDocument::AndroidManifestDocument(AndroidManifestEditorWidget *ed bool AndroidManifestDocument::save(QString *errorString, const QString &fileName, bool autoSave) { m_editorWidget->preSave(); - return TextDocument::save(errorString, fileName, autoSave); + bool result = TextDocument::save(errorString, fileName, autoSave); + m_editorWidget->postSave(); + return result; } QString AndroidManifestDocument::defaultPath() const diff --git a/src/plugins/android/androidmanifesteditorwidget.cpp b/src/plugins/android/androidmanifesteditorwidget.cpp index c74513919db..1d4a138a057 100644 --- a/src/plugins/android/androidmanifesteditorwidget.cpp +++ b/src/plugins/android/androidmanifesteditorwidget.cpp @@ -617,6 +617,16 @@ void AndroidManifestEditorWidget::preSave() updateInfoBar(); } +void AndroidManifestEditorWidget::postSave() +{ + const QString docPath(m_textEditorWidget->textDocument()->filePath().toString()); + ProjectExplorer::Project *project = androidProject(docPath); + if (Target *target = project->activeTarget()) { + AndroidQtSupport *androidQtSupport = AndroidManager::androidQtSupport(target); + androidQtSupport->manifestSaved(target); + } +} + Core::IEditor *AndroidManifestEditorWidget::editor() const { return m_editor; diff --git a/src/plugins/android/androidmanifesteditorwidget.h b/src/plugins/android/androidmanifesteditorwidget.h index fcce653d051..2d0ebdf1acc 100644 --- a/src/plugins/android/androidmanifesteditorwidget.h +++ b/src/plugins/android/androidmanifesteditorwidget.h @@ -105,6 +105,7 @@ public: bool setActivePage(EditorPage page); void preSave(); + void postSave(); Core::IEditor *editor() const; TextEditor::TextEditorWidget *textEditorWidget() const; diff --git a/src/plugins/android/androidqtsupport.h b/src/plugins/android/androidqtsupport.h index b7ee4b52cde..013e28a3b2a 100644 --- a/src/plugins/android/androidqtsupport.h +++ b/src/plugins/android/androidqtsupport.h @@ -66,7 +66,8 @@ public: virtual Utils::FileName apkPath(ProjectExplorer::Target *target) const; virtual Utils::FileName androiddeployqtPath(ProjectExplorer::Target *target) const = 0; virtual Utils::FileName androiddeployJsonPath(ProjectExplorer::Target *target) const = 0; - virtual void resetBuild(const ProjectExplorer::Target *target) = 0; + virtual void manifestSaved(const ProjectExplorer::Target *target) = 0; + virtual Utils::FileName manifestSourcePath(const ProjectExplorer::Target *target) = 0; }; } // namespace Android diff --git a/src/plugins/android/androidqtversion.cpp b/src/plugins/android/androidqtversion.cpp index 45bc0549c21..c23f2e8d64a 100644 --- a/src/plugins/android/androidqtversion.cpp +++ b/src/plugins/android/androidqtversion.cpp @@ -103,24 +103,10 @@ QList AndroidQtVersion::detectQtAbis() const void AndroidQtVersion::addToEnvironment(const Kit *k, Utils::Environment &env) const { + Q_UNUSED(k); // this env vars are used by qmake mkspecs to generate makefiles (check QTDIR/mkspecs/android-g++/qmake.conf for more info) env.set(QLatin1String("ANDROID_NDK_HOST"), AndroidConfigurations::currentConfig().toolchainHost()); env.set(QLatin1String("ANDROID_NDK_ROOT"), AndroidConfigurations::currentConfig().ndkLocation().toUserOutput()); - - Project *project = ProjectTree::currentProject(); - if (!project || !project->activeTarget() - || QtSupport::QtKitInformation::qtVersion(k)->type() != QLatin1String(Constants::ANDROIDQT)) - return; - - Target *target = project->activeTarget(); - if (DeviceTypeKitInformation::deviceTypeId(target->kit()) != Constants::ANDROID_DEVICE_TYPE) - return; - if (AndroidConfigurations::currentConfig().ndkLocation().isEmpty() - || AndroidConfigurations::currentConfig().sdkLocation().isEmpty()) - return; - - env.set(QLatin1String("ANDROID_NDK_PLATFORM"), - AndroidConfigurations::currentConfig().bestNdkPlatformMatch(AndroidManager::minimumSDK(target))); } Utils::Environment AndroidQtVersion::qmakeRunEnvironment() const diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp index 8c6817f6532..12d293cdf65 100644 --- a/src/plugins/projectexplorer/buildconfiguration.cpp +++ b/src/plugins/projectexplorer/buildconfiguration.cpp @@ -235,6 +235,7 @@ Utils::Environment BuildConfiguration::baseEnvironment() const if (useSystemEnvironment()) result = Utils::Environment::systemEnvironment(); target()->kit()->addToEnvironment(result); + addToEnvironment(result); return result; } @@ -259,6 +260,11 @@ void BuildConfiguration::setUseSystemEnvironment(bool b) emitEnvironmentChanged(); } +void BuildConfiguration::addToEnvironment(Utils::Environment &env) const +{ + Q_UNUSED(env); +} + bool BuildConfiguration::useSystemEnvironment() const { return !m_clearSystemEnvironment; @@ -314,10 +320,22 @@ IBuildConfigurationFactory::~IBuildConfigurationFactory() // restore IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, const QVariantMap &map) { - return ExtensionSystem::PluginManager::getObject( - [&parent, map](IBuildConfigurationFactory *factory) { - return factory->canRestore(parent, map); - }); + QList factories + = ExtensionSystem::PluginManager::getObjects( + [&parent, map](IBuildConfigurationFactory *factory) { + return factory->canRestore(parent, map); + }); + + IBuildConfigurationFactory *factory = 0; + int priority = -1; + foreach (IBuildConfigurationFactory *i, factories) { + int iPriority = i->priority(parent); + if (iPriority > priority) { + factory = i; + priority = iPriority; + } + } + return factory; } // setup @@ -357,9 +375,21 @@ IBuildConfigurationFactory * IBuildConfigurationFactory::find(Target *parent) // clone IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, BuildConfiguration *bc) { - return ExtensionSystem::PluginManager::getObject( - [&parent, &bc](IBuildConfigurationFactory *factory) { - return factory->canClone(parent, bc); - }); + QList factories + = ExtensionSystem::PluginManager::getObjects( + [&parent, &bc](IBuildConfigurationFactory *factory) { + return factory->canClone(parent, bc); + }); + + IBuildConfigurationFactory *factory = 0; + int priority = -1; + foreach (IBuildConfigurationFactory *i, factories) { + int iPriority = i->priority(parent); + if (iPriority > priority) { + factory = i; + priority = iPriority; + } + } + return factory; } } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h index fc3e2b7ec24..ebd5b5a3891 100644 --- a/src/plugins/projectexplorer/buildconfiguration.h +++ b/src/plugins/projectexplorer/buildconfiguration.h @@ -70,6 +70,8 @@ public: bool useSystemEnvironment() const; void setUseSystemEnvironment(bool b); + virtual void addToEnvironment(Utils::Environment &env) const; + QList knownStepLists() const; BuildStepList *stepList(Core::Id id) const; @@ -100,13 +102,13 @@ protected: virtual void setBuildDirectory(const Utils::FileName &dir); void cloneSteps(BuildConfiguration *source); + void emitEnvironmentChanged(); private slots: void handleKitUpdate(); void emitBuildDirectoryChanged(); private: - void emitEnvironmentChanged(); void ctor(); bool m_clearSystemEnvironment; diff --git a/src/plugins/qmakeandroidsupport/androidqmakebuildconfigurationfactory.cpp b/src/plugins/qmakeandroidsupport/androidqmakebuildconfigurationfactory.cpp index d1c599d83c6..2e51d28720d 100644 --- a/src/plugins/qmakeandroidsupport/androidqmakebuildconfigurationfactory.cpp +++ b/src/plugins/qmakeandroidsupport/androidqmakebuildconfigurationfactory.cpp @@ -33,9 +33,12 @@ #include "androidpackageinstallationstep.h" #include +#include #include #include +#include + using namespace QmakeAndroidSupport::Internal; int AndroidQmakeBuildConfigurationFactory::priority(const ProjectExplorer::Kit *k, const QString &projectPath) const @@ -54,17 +57,59 @@ int AndroidQmakeBuildConfigurationFactory::priority(const ProjectExplorer::Targe return -1; } -ProjectExplorer::BuildConfiguration *AndroidQmakeBuildConfigurationFactory::create(ProjectExplorer::Target *parent, const ProjectExplorer::BuildInfo *info) const +ProjectExplorer::BuildConfiguration *AndroidQmakeBuildConfigurationFactory::create(ProjectExplorer::Target *parent, + const ProjectExplorer::BuildInfo *info) const { - ProjectExplorer::BuildConfiguration *bc = QmakeBuildConfigurationFactory::create(parent, info); + auto qmakeInfo = static_cast(info); + AndroidQmakeBuildConfiguration *bc = new AndroidQmakeBuildConfiguration(parent); + configureBuildConfiguration(parent, bc, qmakeInfo); + ProjectExplorer::BuildStepList *buildSteps = bc->stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD)); buildSteps->insertStep(2, new AndroidPackageInstallationStep(buildSteps)); buildSteps->insertStep(3, new QmakeAndroidBuildApkStep(buildSteps)); - return bc; } -// should the buildconfiguration have its own id? -// and implement restore/clone then? +ProjectExplorer::BuildConfiguration *AndroidQmakeBuildConfigurationFactory::clone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) +{ + if (!canClone(parent, source)) + return 0; + AndroidQmakeBuildConfiguration *oldbc(static_cast(source)); + return new AndroidQmakeBuildConfiguration(parent, oldbc); +} + +ProjectExplorer::BuildConfiguration *AndroidQmakeBuildConfigurationFactory::restore(ProjectExplorer::Target *parent, const QVariantMap &map) +{ + if (!canRestore(parent, map)) + return 0; + AndroidQmakeBuildConfiguration *bc = new AndroidQmakeBuildConfiguration(parent); + if (bc->fromMap(map)) + return bc; + delete bc; + return 0; +} +AndroidQmakeBuildConfiguration::AndroidQmakeBuildConfiguration(ProjectExplorer::Target *target) + : QmakeProjectManager::QmakeBuildConfiguration(target) +{ + +} + +AndroidQmakeBuildConfiguration::AndroidQmakeBuildConfiguration(ProjectExplorer::Target *target, AndroidQmakeBuildConfiguration *source) + : QmakeProjectManager::QmakeBuildConfiguration(target, source) +{ + +} + +AndroidQmakeBuildConfiguration::AndroidQmakeBuildConfiguration(ProjectExplorer::Target *target, Core::Id id) + : QmakeProjectManager::QmakeBuildConfiguration(target, id) +{ + +} + +void AndroidQmakeBuildConfiguration::addToEnvironment(Utils::Environment &env) const +{ + env.set(QLatin1String("ANDROID_NDK_PLATFORM"), + Android::AndroidConfigurations::currentConfig().bestNdkPlatformMatch(Android::AndroidManager::minimumSDK(target()))); +} diff --git a/src/plugins/qmakeandroidsupport/androidqmakebuildconfigurationfactory.h b/src/plugins/qmakeandroidsupport/androidqmakebuildconfigurationfactory.h index 0b917e6c5af..900a57855da 100644 --- a/src/plugins/qmakeandroidsupport/androidqmakebuildconfigurationfactory.h +++ b/src/plugins/qmakeandroidsupport/androidqmakebuildconfigurationfactory.h @@ -48,8 +48,21 @@ public: ProjectExplorer::BuildConfiguration *create(ProjectExplorer::Target *parent, const ProjectExplorer::BuildInfo *info) const; - // The clone and restore from QmakeBuildConfigurationFactory - // work for us too. + ProjectExplorer::BuildConfiguration *clone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source); + ProjectExplorer::BuildConfiguration *restore(ProjectExplorer::Target *parent, const QVariantMap &map); +}; + +class AndroidQmakeBuildConfiguration : public QmakeProjectManager::QmakeBuildConfiguration +{ + friend class AndroidQmakeBuildConfigurationFactory; + Q_OBJECT +public: + explicit AndroidQmakeBuildConfiguration(ProjectExplorer::Target *target); + AndroidQmakeBuildConfiguration(ProjectExplorer::Target *target, AndroidQmakeBuildConfiguration *source); + AndroidQmakeBuildConfiguration(ProjectExplorer::Target *target, Core::Id id); + void addToEnvironment(Utils::Environment &env) const; + + using BuildConfiguration::emitEnvironmentChanged; }; } // namespace Internal diff --git a/src/plugins/qmakeandroidsupport/qmakeandroidsupport.cpp b/src/plugins/qmakeandroidsupport/qmakeandroidsupport.cpp index f81cae8de5c..229dbb12548 100644 --- a/src/plugins/qmakeandroidsupport/qmakeandroidsupport.cpp +++ b/src/plugins/qmakeandroidsupport/qmakeandroidsupport.cpp @@ -31,6 +31,8 @@ #include "androidpackageinstallationstep.h" #include "qmakeandroidbuildapkstep.h" #include "qmakeandroidsupport.h" +#include "androidqmakebuildconfigurationfactory.h" +#include "qmakeandroidrunconfiguration.h" #include #include @@ -131,27 +133,42 @@ Utils::FileName QmakeAndroidSupport::androiddeployJsonPath(ProjectExplorer::Targ return Utils::FileName::fromString(inputFile); } -void QmakeAndroidSupport::resetBuild(const ProjectExplorer::Target *target) +void QmakeAndroidSupport::manifestSaved(const ProjectExplorer::Target *target) { - QmakeBuildConfiguration *bc = qobject_cast(target->activeBuildConfiguration()); - if (!bc) - return; + ProjectExplorer::BuildConfiguration *bc = target->activeBuildConfiguration(); + if (auto qbc = qobject_cast(bc)) { + qbc->emitEnvironmentChanged(); - QMakeStep *qs = bc->qmakeStep(); - if (!qs) - return; + QMakeStep *qs = qbc->qmakeStep(); + if (!qs) + return; - qs->setForced(true); + qs->setForced(true); - ProjectExplorer::BuildManager::buildList(bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN), - ProjectExplorer::ProjectExplorerPlugin::displayNameForStepId(ProjectExplorer::Constants::BUILDSTEPS_CLEAN)); - ProjectExplorer::BuildManager::appendStep(qs, ProjectExplorer::ProjectExplorerPlugin::displayNameForStepId(ProjectExplorer::Constants::BUILDSTEPS_CLEAN)); - bc->setSubNodeBuild(0); - // Make the buildconfiguration emit a evironmentChanged() signal - // TODO find a better way - bool use = bc->useSystemEnvironment(); - bc->setUseSystemEnvironment(!use); - bc->setUseSystemEnvironment(use); + ProjectExplorer::BuildManager::buildList(bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN), + ProjectExplorer::ProjectExplorerPlugin::displayNameForStepId(ProjectExplorer::Constants::BUILDSTEPS_CLEAN)); + ProjectExplorer::BuildManager::appendStep(qs, ProjectExplorer::ProjectExplorerPlugin::displayNameForStepId(ProjectExplorer::Constants::BUILDSTEPS_CLEAN)); + qbc->setSubNodeBuild(0); + } +} + +Utils::FileName QmakeAndroidSupport::manifestSourcePath(const ProjectExplorer::Target *target) +{ + ProjectExplorer::RunConfiguration *rc = target->activeRunConfiguration(); + if (auto qrc = qobject_cast(rc)) { + QString proFilePath = qrc->proFilePath(); + const auto project = static_cast(target->project()); + const QmakeProFileNode *node = project->rootQmakeProjectNode()->findProFileFor(proFilePath); + if (node) { + QString packageSource = node->singleVariableValue(AndroidPackageSourceDir); + if (!packageSource.isEmpty()) { + Utils::FileName manifest = Utils::FileName::fromUserInput(packageSource + QLatin1String("/AndroidManifest.xml")); + if (manifest.exists()) + return manifest; + } + } + } + return Utils::FileName(); } } // namespace Internal diff --git a/src/plugins/qmakeandroidsupport/qmakeandroidsupport.h b/src/plugins/qmakeandroidsupport/qmakeandroidsupport.h index e274dd4a808..5c19c9498cb 100644 --- a/src/plugins/qmakeandroidsupport/qmakeandroidsupport.h +++ b/src/plugins/qmakeandroidsupport/qmakeandroidsupport.h @@ -47,7 +47,8 @@ public: Utils::FileName androiddeployqtPath(ProjectExplorer::Target *target) const; Utils::FileName androiddeployJsonPath(ProjectExplorer::Target *target) const; - void resetBuild(const ProjectExplorer::Target *target); + void manifestSaved(const ProjectExplorer::Target *target); + Utils::FileName manifestSourcePath(const ProjectExplorer::Target *target); }; } // namespace Internal diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp index 7cfc1964eb0..2241309fda1 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp @@ -699,16 +699,11 @@ QList QmakeBuildConfigurationFactory::availableSetups(const Kit *k, return result; } -BuildConfiguration *QmakeBuildConfigurationFactory::create(Target *parent, const BuildInfo *info) const +void QmakeBuildConfigurationFactory::configureBuildConfiguration(Target *parent, + QmakeBuildConfiguration *bc, + const QmakeBuildInfo *qmakeInfo) const { - QTC_ASSERT(info->factory() == this, return 0); - QTC_ASSERT(info->kitId == parent->kit()->id(), return 0); - QTC_ASSERT(!info->displayName.isEmpty(), return 0); - - const QmakeBuildInfo *qmakeInfo = static_cast(info); - BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(parent->kit()); - QTC_ASSERT(version, return 0); BaseQtVersion::QmakeBuildConfigs config = version->defaultBuildConfig(); if (qmakeInfo->type == BuildConfiguration::Release) @@ -716,9 +711,8 @@ BuildConfiguration *QmakeBuildConfigurationFactory::create(Target *parent, const else config |= QtSupport::BaseQtVersion::DebugBuild; - QmakeBuildConfiguration *bc = new QmakeBuildConfiguration(parent); - bc->setDefaultDisplayName(info->displayName); - bc->setDisplayName(info->displayName); + bc->setDefaultDisplayName(qmakeInfo->displayName); + bc->setDisplayName(qmakeInfo->displayName); BuildStepList *buildSteps = bc->stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD)); BuildStepList *cleanSteps = bc->stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_CLEAN)); @@ -751,10 +745,21 @@ BuildConfiguration *QmakeBuildConfigurationFactory::create(Target *parent, const if (directory.isEmpty()) { directory = defaultBuildDirectory(qmakeInfo->supportsShadowBuild, parent->project()->projectFilePath().toString(), - parent->kit(), info->displayName); + parent->kit(), qmakeInfo->displayName); } bc->setBuildDirectory(directory); +} + +BuildConfiguration *QmakeBuildConfigurationFactory::create(Target *parent, const BuildInfo *info) const +{ + QTC_ASSERT(info->factory() == this, return 0); + QTC_ASSERT(info->kitId == parent->kit()->id(), return 0); + QTC_ASSERT(!info->displayName.isEmpty(), return 0); + + const QmakeBuildInfo *qmakeInfo = static_cast(info); + QmakeBuildConfiguration *bc = new QmakeBuildConfiguration(parent); + configureBuildConfiguration(parent, bc, qmakeInfo); return bc; } diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h index a5e290e71c0..be178558f76 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h @@ -129,11 +129,11 @@ protected: QmakeBuildConfiguration(ProjectExplorer::Target *target, QmakeBuildConfiguration *source); QmakeBuildConfiguration(ProjectExplorer::Target *target, Core::Id id); virtual bool fromMap(const QVariantMap &map); + void setBuildDirectory(const Utils::FileName &directory); private: void ctor(); QString defaultShadowBuildDirectory() const; - void setBuildDirectory(const Utils::FileName &directory); void updateShadowBuild(); class LastKitState @@ -182,6 +182,8 @@ public: ProjectExplorer::BuildConfiguration *clone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source); bool canRestore(const ProjectExplorer::Target *parent, const QVariantMap &map) const; ProjectExplorer::BuildConfiguration *restore(ProjectExplorer::Target *parent, const QVariantMap &map); +protected: + void configureBuildConfiguration(ProjectExplorer::Target *parent, QmakeBuildConfiguration *bc, const QmakeBuildInfo *info) const; private slots: void update();