From 7789ba45f07017b513cc74aa80fdc10a3cfc325d Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Tue, 5 Mar 2013 14:20:00 +0100 Subject: [PATCH] Android: Also include indirect dependencies in libs.xml Change-Id: I12d5aff64fc6b677ac88c28eed90ae51443c7584 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/android/androidmanager.cpp | 29 +++--- src/plugins/android/androidmanager.h | 23 ++--- .../android/androidpackagecreationstep.cpp | 90 ++++++++++++++----- .../android/androidpackagecreationstep.h | 3 +- 4 files changed, 95 insertions(+), 50 deletions(-) diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 2910964b3fe..449a80575c5 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -576,15 +576,15 @@ QString AndroidManager::loadLocalJarsInitClasses(ProjectExplorer::Target *target return loadLocal(target, apiLevel, Jar, QLatin1String("initClass")); } -QStringList AndroidManager::availableQtLibs(ProjectExplorer::Target *target) +QVector AndroidManager::availableQtLibsWithDependencies(ProjectExplorer::Target *target) { QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target->kit()); if (!target->activeRunConfiguration()) - return QStringList(); + return QVector(); ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(target->kit()); if (tc->type() != QLatin1String(Constants::ANDROID_TOOLCHAIN_TYPE)) - return QStringList(); + return QVector(); Qt4ProjectManager::Qt4Project *project = static_cast(target->project()); QString arch = project->rootQt4ProjectNode()->singleVariableValue(Qt4ProjectManager::AndroidArchVar); @@ -594,20 +594,13 @@ QStringList AndroidManager::availableQtLibs(ProjectExplorer::Target *target) Utils::FileName readelfPath = AndroidConfigurations::instance().readelfPath(target->activeRunConfiguration()->abi().architecture(), atc->ndkToolChainVersion()); - QStringList libs; const Qt4ProjectManager::Qt4Project *const qt4Project = qobject_cast(target->project()); if (!qt4Project || !version) - return libs; + return QVector(); QString qtLibsPath = version->qmakeProperty("QT_INSTALL_LIBS"); if (!readelfPath.toFileInfo().exists()) { - QDirIterator libsIt(qtLibsPath, QStringList() << QLatin1String("libQt*.so")); - while (libsIt.hasNext()) { - libsIt.next(); - libs << libsIt.fileName().mid(3, libsIt.fileName().indexOf(QLatin1Char('.')) - 3); - } - libs.sort(); - return libs; + return QVector(); } LibrariesMap mapLibs; QDir libPath; @@ -652,9 +645,17 @@ QStringList AndroidManager::availableQtLibs(ProjectExplorer::Target *target) qtLibraries.push_back(mapLibs[key]); } qSort(qtLibraries.begin(), qtLibraries.end(), qtLibrariesLessThan); - foreach (Library lib, qtLibraries) { + + return qtLibraries; + +} + +QStringList AndroidManager::availableQtLibs(ProjectExplorer::Target *target) +{ + QStringList libs; + QVector qtLibraries = availableQtLibsWithDependencies(target); + foreach (Library lib, qtLibraries) libs.push_back(lib.name); - } return libs; } diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index 22bd5a64948..a03e0980174 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -104,6 +104,18 @@ public: static QString loadLocalJars(ProjectExplorer::Target *target, int apiLevel); static QString loadLocalJarsInitClasses(ProjectExplorer::Target *target, int apiLevel); + class Library + { + public: + Library() + { level = -1; } + int level; + QStringList dependencies; + QString name; + }; + typedef QMap LibrariesMap; + + static QVector availableQtLibsWithDependencies(ProjectExplorer::Target *target); static QStringList availableQtLibs(ProjectExplorer::Target *target); static QStringList qtLibs(ProjectExplorer::Target *target); static bool setQtLibs(ProjectExplorer::Target *target, const QStringList &libs); @@ -132,17 +144,6 @@ private: }; static QString loadLocal(ProjectExplorer::Target *target, int apiLevel, ItemType item, const QString &attribute=QLatin1String("file")); - class Library - { - public: - Library() - { level = -1; } - int level; - QStringList dependencies; - QString name; - }; - typedef QMap LibrariesMap; - enum IconType { HighDPI, diff --git a/src/plugins/android/androidpackagecreationstep.cpp b/src/plugins/android/androidpackagecreationstep.cpp index 947fda77c9d..d52d0952655 100644 --- a/src/plugins/android/androidpackagecreationstep.cpp +++ b/src/plugins/android/androidpackagecreationstep.cpp @@ -213,6 +213,57 @@ static void parseSharedLibs(const QByteArray &buffer, QStringList *libs) } } +void markNeeded(const QString &library, + const QVector &dependencies, + QMap *neededMap) +{ + if (!neededMap->contains(library)) + return; + if (neededMap->value(library)) + return; + neededMap->insert(library, true); + for (int i = 0; i < dependencies.size(); ++i) { + if (dependencies.at(i).name == library) { + foreach (const QString &dependency, dependencies.at(i).dependencies) + markNeeded(dependency, dependencies, neededMap); + break; + } + } +} + +QStringList requiredLibraries(QVector availableLibraries, + const QStringList &checkedLibs, const QStringList &dependencies) +{ + QMap neededLibraries; + QVector::const_iterator it, end; + it = availableLibraries.constBegin(); + end = availableLibraries.constEnd(); + + for (; it != end; ++it) + neededLibraries[(*it).name] = false; + + // Checked items are always needed + foreach (const QString &lib, checkedLibs) + markNeeded(lib, availableLibraries, &neededLibraries); + + foreach (const QString &lib, dependencies) { + if (lib.startsWith(QLatin1String("lib")) + && lib.endsWith(QLatin1String(".so"))) + markNeeded(lib.mid(3, lib.size() - 6), availableLibraries, &neededLibraries); + } + + for (int i = availableLibraries.size() - 1; i>= 0; --i) + if (!neededLibraries.value(availableLibraries.at(i).name)) + availableLibraries.remove(i); + + QStringList requiredLibraries; + foreach (const AndroidManager::Library &lib, availableLibraries) { + if (neededLibraries.value(lib.name)) + requiredLibraries << lib.name; + } + return requiredLibraries; +} + void AndroidPackageCreationStep::checkRequiredLibraries() { QProcess readelfProc; @@ -235,21 +286,16 @@ void AndroidPackageCreationStep::checkRequiredLibraries() } QStringList libs; parseSharedLibs(readelfProc.readAll(), &libs); - QStringList checkedLibs = AndroidManager::qtLibs(target()); - QStringList requiredLibraries; - foreach (const QString &qtLib, AndroidManager::availableQtLibs(target())) { - if (libs.contains(QLatin1String("lib") + qtLib + QLatin1String(".so")) || checkedLibs.contains(qtLib)) - requiredLibraries << qtLib; - } - AndroidManager::setQtLibs(target(), requiredLibraries); + AndroidManager::setQtLibs(target(), requiredLibraries(AndroidManager::availableQtLibsWithDependencies(target()), + AndroidManager::qtLibs(target()), libs)); - checkedLibs = AndroidManager::prebundledLibs(target()); - requiredLibraries.clear(); + QStringList checkedLibs = AndroidManager::prebundledLibs(target()); + QStringList prebundledLibraries; foreach (const QString &qtLib, AndroidManager::availableQtLibs(target())) { if (libs.contains(qtLib) || checkedLibs.contains(qtLib)) - requiredLibraries << qtLib; + prebundledLibraries << qtLib; } - AndroidManager::setPrebundledLibs(target(), requiredLibraries); + AndroidManager::setPrebundledLibs(target(), prebundledLibraries); emit updateRequiredLibrariesModels(); } @@ -264,7 +310,7 @@ void AndroidPackageCreationStep::initCheckRequiredLibrariesForRun() m_readElf = AndroidConfigurations::instance().readelfPath(target()->activeRunConfiguration()->abi().architecture(), atc->ndkToolChainVersion()); m_qtLibs = AndroidManager::qtLibs(target()); - m_availableQtLibs = AndroidManager::availableQtLibs(target()); + m_availableQtLibs = AndroidManager::availableQtLibsWithDependencies(target()); m_prebundledLibs = AndroidManager::prebundledLibs(target()); } @@ -282,22 +328,18 @@ void AndroidPackageCreationStep::checkRequiredLibrariesForRun() } QStringList libs; parseSharedLibs(readelfProc.readAll(), &libs); - QStringList requiredLibraries; - foreach (const QString &qtLib, m_availableQtLibs) { - if (libs.contains(QLatin1String("lib") + qtLib + QLatin1String(".so")) || m_qtLibs.contains(qtLib)) - requiredLibraries << qtLib; - } - QMetaObject::invokeMethod(this, "setQtLibs",Qt::BlockingQueuedConnection, - Q_ARG(QStringList, requiredLibraries)); - requiredLibraries.clear(); - foreach (const QString &qtLib, m_availableQtLibs) { - if (libs.contains(qtLib) || m_prebundledLibs.contains(qtLib)) - requiredLibraries << qtLib; + QMetaObject::invokeMethod(this, "setQtLibs",Qt::BlockingQueuedConnection, + Q_ARG(QStringList, requiredLibraries(m_availableQtLibs, m_qtLibs, libs))); + + QStringList prebundledLibraries; + foreach (const AndroidManager::Library &qtLib, m_availableQtLibs) { + if (libs.contains(qtLib.name) || m_prebundledLibs.contains(qtLib.name)) + prebundledLibraries << qtLib.name; } QMetaObject::invokeMethod(this, "setPrebundledLibs", Qt::BlockingQueuedConnection, - Q_ARG(QStringList, requiredLibraries)); + Q_ARG(QStringList, prebundledLibraries)); emit updateRequiredLibrariesModels(); } diff --git a/src/plugins/android/androidpackagecreationstep.h b/src/plugins/android/androidpackagecreationstep.h index c842ab3322e..13a6fd96938 100644 --- a/src/plugins/android/androidpackagecreationstep.h +++ b/src/plugins/android/androidpackagecreationstep.h @@ -31,6 +31,7 @@ #define ANDROIDPACKAGECREATIONSTEP_H #include "javaparser.h" +#include "androidmanager.h" #include #include @@ -125,7 +126,7 @@ private: Utils::FileName m_appPath; Utils::FileName m_readElf; QStringList m_qtLibs; - QStringList m_availableQtLibs; + QVector m_availableQtLibs; QStringList m_prebundledLibs; };