Add Qt plugins to the dependency list with their dependencies

In androiddeployqt we try to add all plugins that belong to the Qt
modules that Android application links. This works in case if all the
plugin dependencies are linked to the Android application explicitly
or implicitly using a build system linking mechanism. But plugins may
have dependencies that should be resolved implicitly by
androiddeployqt. The following situation is handled by this change:

 App1 links QtLib1.so
 QtLib1.so promotes its plugin plugin1.so to be included to an apk
 plugin1.so links QtLib2.so

In the described example App1 expects that plugin1.so with all the
dependencies is deployed to an apk without the need of linking
QtLib2.so explicitly.

There is a negative side effect of this change. plugin1.so is added to
apk unconditionally so there could be a situation when the plugin is
unused. So QtLib2.so with its dependencies will be included to an apk
without necessity and will increase the size of the apk significantly.

Cleanup forward declarations in androiddeployqt's main.cpp by moving
them to the top of the file.

TODO: Need to add the API which allows to exclude such plugins from apk
or to specify the list of essential plugins that are used in the
Android application. See QTBUG-107634 for details.

[ChangeLog][Android] All plugins that belong to the Qt modules that are
linked to the Android application are now deployed with their
dependencies. androiddeployqt tries to find and resolve plugin
dependencies implicitly instead of skipping plugins with dependencies
that are not resolved explicitly in the user project.

Fixes: QTBUG-107589
Fixes: QTBUG-106035
Change-Id: Ib6d9abd74ae5e21e856d7ccd02789a7a65602f40
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
Alexey Edelev 2022-10-13 16:28:38 +02:00
parent b3ce494bac
commit 54c959643e

View File

@ -227,6 +227,12 @@ static const QHash<QByteArray, QByteArray> elfArchitectures = {
{"x86_64", "x86_64"}
};
bool goodToCopy(const Options *options, const QString &file, QStringList *unmetDependencies);
bool checkCanImportFromRootPaths(const Options *options, const QString &absolutePath,
const QUrl &moduleUrl);
bool readDependenciesFromElf(Options *options, const QString &fileName,
QSet<QString> *usedDependencies, QSet<QString> *remainingDependencies);
QString architectureFromName(const QString &name)
{
QRegularExpression architecture(QStringLiteral("_(armeabi-v7a|arm64-v8a|x86|x86_64).so$"));
@ -1772,6 +1778,11 @@ bool readAndroidDependencyXml(Options *options,
if (usedDependencies->contains(fileName.absolutePath))
continue;
if (fileName.absolutePath.endsWith(".so"_L1)) {
QSet<QString> remainingDependencies;
readDependenciesFromElf(options, fileName.absolutePath,
usedDependencies, &remainingDependencies);
}
usedDependencies->insert(fileName.absolutePath);
if (options->verbose)
@ -1926,10 +1937,6 @@ bool readDependenciesFromElf(Options *options,
return true;
}
bool goodToCopy(const Options *options, const QString &file, QStringList *unmetDependencies);
bool checkCanImportFromRootPaths(const Options *options, const QString &absolutePath,
const QUrl &moduleUrl);
bool scanImports(Options *options, QSet<QString> *usedDependencies)
{
if (options->verbose)