Android: activate tst_QPluginLoader

- Use QT_ANDROID_EXTRA_LIBS to correctly deploy libraries on Android.
- Update the test code to use application libraries directory
  on Android.

This allows to enable the test for Android in CMakeLists.txt

Task-number: QTBUG-87438
Pick-to: 6.3 6.2
Change-Id: Ib74da036472320736888052b63a45ca50431de48
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
Ivan Solovev 2022-03-28 13:28:25 +02:00
parent ed6fe5abc8
commit 7c9b4f86b6
4 changed files with 65 additions and 9 deletions

View File

@ -5,10 +5,7 @@ if(QT_BUILD_SHARED_LIBS)
endif()
add_subdirectory(quuid)
if(QT_FEATURE_library)
# QTBUG-87438 # special case
if(NOT ANDROID)
add_subdirectory(qpluginloader)
endif()
add_subdirectory(qpluginloader)
add_subdirectory(qlibrary)
endif()
if(QT_BUILD_SHARED_LIBS AND QT_FEATURE_library)

View File

@ -8,7 +8,7 @@ qt_internal_add_cmake_library(staticplugin
STATIC
SOURCES
main.cpp
PUBLIC_LIBRARIES
LIBRARIES
Qt::Core
MOC_OPTIONS
"-M"

View File

@ -14,16 +14,43 @@ qt_internal_add_test(tst_qpluginloader
../fakeplugin.cpp
../theplugin/plugininterface.h
../tst_qpluginloader.cpp
PUBLIC_LIBRARIES
LIBRARIES
staticplugin
TESTDATA ${test_data}
)
add_dependencies(tst_qpluginloader tst_qpluginloaderlib staticplugin theplugin)
if (UNIX)
if(NOT APPLE)
add_dependencies(tst_qpluginloader theoldplugin)
endif()
if (NOT ANDROID AND NOT APPLE)
add_dependencies(tst_qpluginloader almostplugin)
endif()
endif()
if(ANDROID)
add_compile_definitions(ANDROID_ARCH="${CMAKE_ANDROID_ARCH_ABI}")
set(plugins
theplugin
theoldplugin
tst_qpluginloaderlib
)
set(extra_libs)
foreach(plugin IN LISTS plugins)
list(APPEND extra_libs
"${CMAKE_CURRENT_BINARY_DIR}/../bin/lib${plugin}_${CMAKE_ANDROID_ARCH_ABI}.so")
endforeach()
set_target_properties(tst_qpluginloader PROPERTIES
QT_ANDROID_EXTRA_LIBS "${extra_libs}"
)
endif()
## Scopes:
#####################################################################
qt_internal_extend_target(tst_qpluginloader CONDITION QT_FEATURE_private_tests
PUBLIC_LIBRARIES
LIBRARIES
Qt::CorePrivate
)

View File

@ -185,12 +185,22 @@ static std::unique_ptr<QTemporaryFile> patchElf(const QString &source, ElfPatche
static QString sys_qualifiedLibraryName(const QString &fileName)
{
#ifdef Q_OS_ANDROID
// On Android all the libraries must be located in the APK's libs subdir
const QStringList paths = QCoreApplication::libraryPaths();
if (!paths.isEmpty()) {
return QLatin1String("%1/%2%3_%4%5").arg(paths.first(), PREFIX, fileName,
ANDROID_ARCH, SUFFIX);
}
return fileName;
#else
QString name = QLatin1String("bin/") + QLatin1String(PREFIX) + fileName + QLatin1String(SUFFIX);
const QString libname = QFINDTESTDATA(name);
QFileInfo fi(libname);
if (fi.exists())
return fi.canonicalFilePath();
return libname;
#endif
}
QT_FORWARD_DECLARE_CLASS(QPluginLoader)
@ -918,11 +928,19 @@ void tst_QPluginLoader::relativePath()
#if !defined(QT_SHARED)
QSKIP("This test requires Qt to create shared libraries.");
#endif
#ifdef Q_OS_ANDROID
// On Android we do not need to explicitly set library paths, as they are
// already set.
// But we need to use ARCH suffix in pulgin name
const QString pluginName("theplugin_" ANDROID_ARCH SUFFIX);
#else
// Windows binaries run from release and debug subdirs, so we can't rely on the current dir.
const QString binDir = QFINDTESTDATA("bin");
QVERIFY(!binDir.isEmpty());
QCoreApplication::addLibraryPath(binDir);
QPluginLoader loader("theplugin" SUFFIX);
const QString pluginName("theplugin" SUFFIX);
#endif
QPluginLoader loader(pluginName);
loader.load(); // not recommended, instance() should do the job.
PluginInterface *instance = qobject_cast<PluginInterface*>(loader.instance());
QVERIFY(instance);
@ -935,13 +953,27 @@ void tst_QPluginLoader::absolutePath()
#if !defined(QT_SHARED)
QSKIP("This test requires Qt to create shared libraries.");
#endif
#ifdef Q_OS_ANDROID
// On Android we need to clear library paths to make sure that the absolute
// path works
const QStringList libraryPaths = QCoreApplication::libraryPaths();
QVERIFY(!libraryPaths.isEmpty());
QCoreApplication::setLibraryPaths(QStringList());
const QString pluginPath(libraryPaths.first() + "/" PREFIX "theplugin_" ANDROID_ARCH SUFFIX);
#else
// Windows binaries run from release and debug subdirs, so we can't rely on the current dir.
const QString binDir = QFINDTESTDATA("bin");
QVERIFY(!binDir.isEmpty());
QVERIFY(QDir::isAbsolutePath(binDir));
QPluginLoader loader(binDir + "/" PREFIX "theplugin" SUFFIX);
const QString pluginPath(binDir + "/" PREFIX "theplugin" SUFFIX);
#endif
QPluginLoader loader(pluginPath);
loader.load(); // not recommended, instance() should do the job.
PluginInterface *instance = qobject_cast<PluginInterface*>(loader.instance());
#ifdef Q_OS_ANDROID
// Restore library paths
QCoreApplication::setLibraryPaths(libraryPaths);
#endif
QVERIFY(instance);
QCOMPARE(instance->pluginName(), QLatin1String("Plugin ok"));
QVERIFY(loader.unload());