Android: activate tst_qfactoryloader

- Use QT_ANDROID_EXTRA_PLUGINS to specify a correct plugins directory
- Update plugin names on Android to match the expected format
- Add explicit dependency on the plugins, so that they always get built
  and included in the APK
- Update the test code to respect the fact that plugins are packed
  differently on Android.

All these steps allow to enable this test for Android in CMakeLists.txt

Task-number: QTBUG-87438
Pick-to: 6.3 6.2
Change-Id: I09e389c761688cea216d8922b94ea3a2600f7a67
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
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-24 17:20:46 +01:00
parent 904d613a51
commit 862f42e806
5 changed files with 50 additions and 76 deletions

View File

@ -1,7 +1,6 @@
# Generated from plugin.pro.
# QTBUG-87438 # special case
if(QT_BUILD_SHARED_LIBS AND NOT ANDROID)
if(QT_BUILD_SHARED_LIBS)
add_subdirectory(qfactoryloader)
endif()
add_subdirectory(quuid)

View File

@ -4,7 +4,7 @@
## plugin1 Generic Library:
#####################################################################
qt_internal_add_cmake_library(plugin1
qt_internal_add_cmake_library(tst_qfactoryloader_plugin1
MODULE
INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qfactoryloader/bin"
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../bin"
@ -14,17 +14,17 @@ qt_internal_add_cmake_library(plugin1
Qt::Core
)
#### Keys ignored in scope 1:.:.:plugin1.pro:<TRUE>:
# INSTALLS = "target"
# TEMPLATE = "lib"
# target.path = "$$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin"
if(ANDROID)
# On Android the plugins must match the following mask:
# "libplugins_{suffix}_*.so"
# and the testcase uses "bin" as a suffix
set_target_properties(tst_qfactoryloader_plugin1 PROPERTIES
OUTPUT_NAME "plugins_bin_tst_qfactoryloader_plugin1")
endif()
## Scopes:
#####################################################################
qt_internal_extend_target(plugin1 CONDITION NOT QT_FEATURE_library
qt_internal_extend_target(tst_qfactoryloader_plugin1 CONDITION NOT QT_FEATURE_library
DEFINES
QT_STATICPLUGIN
)
qt_autogen_tools_initial_setup(plugin1)
qt_autogen_tools_initial_setup(tst_qfactoryloader_plugin1)

View File

@ -4,7 +4,7 @@
## plugin2 Generic Library:
#####################################################################
qt_internal_add_cmake_library(plugin2
qt_internal_add_cmake_library(tst_qfactoryloader_plugin2
MODULE
INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qfactoryloader/bin"
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../bin"
@ -14,17 +14,17 @@ qt_internal_add_cmake_library(plugin2
Qt::Core
)
#### Keys ignored in scope 1:.:.:plugin2.pro:<TRUE>:
# INSTALLS = "target"
# TEMPLATE = "lib"
# target.path = "$$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin"
if(ANDROID)
# On Android the plugins must match the following mask:
# "libplugins_{suffix}_*.so"
# and the testcase uses "bin" as a suffix
set_target_properties(tst_qfactoryloader_plugin2 PROPERTIES
OUTPUT_NAME "plugins_bin_tst_qfactoryloader_plugin2")
endif()
## Scopes:
#####################################################################
qt_internal_extend_target(plugin2 CONDITION NOT QT_FEATURE_library
qt_internal_extend_target(tst_qfactoryloader_plugin2 CONDITION NOT QT_FEATURE_library
DEFINES
QT_STATICPLUGIN
)
qt_autogen_tools_initial_setup(plugin2)
qt_autogen_tools_initial_setup(tst_qfactoryloader_plugin2)

View File

@ -10,60 +10,24 @@ qt_internal_add_test(tst_qfactoryloader
../plugin1/plugininterface1.h
../plugin2/plugininterface2.h
../tst_qfactoryloader.cpp
PUBLIC_LIBRARIES
LIBRARIES
Qt::CorePrivate
)
## Scopes:
#####################################################################
# special case begin
if (NOT QT_FEATURE_library)
target_link_directories(tst_qfactoryloader PRIVATE "${CMAKE_CURRENT_BINARY_DIR}../bin")
endif()
# special case end
qt_internal_extend_target(tst_qfactoryloader CONDITION NOT QT_FEATURE_library
PUBLIC_LIBRARIES
# Remove: L
# special case begin
# this part is handled as a special case above
# ../bin/
# special case end
LIBRARIES
tst_qfactoryloader_plugin1
tst_qfactoryloader_plugin2
)
add_dependencies(tst_qfactoryloader tst_qfactoryloader_plugin1 tst_qfactoryloader_plugin2)
if(ANDROID)
# special case begin
set_source_files_properties(
${CMAKE_CURRENT_BINARY_DIR}/../bin/libplugin1.so
PROPERTIES QT_RESOURCE_TARGET_DEPENDENCY plugin1
)
set_source_files_properties(
${CMAKE_CURRENT_BINARY_DIR}/../bin/libplugin2.so
PROPERTIES QT_RESOURCE_TARGET_DEPENDENCY plugin2
)
# Resources:
if (ANDROID)
set(qmake_libs_resource_files
bin/libplugin1_${CMAKE_ANDROID_ARCH_ABI}.so
bin/libplugin2_${CMAKE_ANDROID_ARCH_ABI}.so
)
else()
set(qmake_libs_resource_files
bin/libplugin1.so
bin/libplugin2.so
)
endif()
list(TRANSFORM qmake_libs_resource_files PREPEND "${CMAKE_CURRENT_BINARY_DIR}/../")
# special case end
qt_internal_add_resource(tst_qfactoryloader "qmake_libs"
PREFIX
"android_test_data"
BASE
"${CMAKE_CURRENT_BINARY_DIR}/.."
FILES
${qmake_libs_resource_files}
# QT_ANDROID_EXTRA_PLUGINS requires a list of directories, not files!
set_target_properties(tst_qfactoryloader PROPERTIES
QT_ANDROID_EXTRA_PLUGINS "${CMAKE_CURRENT_BINARY_DIR}/../bin"
)
endif()

View File

@ -60,19 +60,16 @@ static const char binFolderC[] = "bin";
void tst_QFactoryLoader::initTestCase()
{
#ifdef Q_OS_ANDROID
directory = QEXTRACTTESTDATA("android_test_data");
QVERIFY(directory);
QVERIFY(directory->isValid());
QVERIFY2(QDir::setCurrent(directory->path()), qPrintable("Could not chdir to " + directory->path()));
#endif
// On Android the plugins are bundled into APK's libs subdir
#ifndef Q_OS_ANDROID
binFolder = QFINDTESTDATA(binFolderC);
QVERIFY2(!binFolder.isEmpty(), "Unable to locate 'bin' folder");
#endif
}
void tst_QFactoryLoader::usingTwoFactoriesFromSameDir()
{
#if QT_CONFIG(library)
#if QT_CONFIG(library) && !defined(Q_OS_ANDROID)
// set the library path to contain the directory where the 'bin' dir is located
QCoreApplication::setLibraryPaths( { QFileInfo(binFolder).absolutePath() });
#endif
@ -101,15 +98,29 @@ void tst_QFactoryLoader::extraSearchPath()
#if defined(Q_OS_ANDROID) && !QT_CONFIG(library)
QSKIP("Test not applicable in this configuration.");
#else
#ifdef Q_OS_ANDROID
// On Android the libs are not stored in binFolder, but bundled into
// APK's libs subdir
const QStringList androidLibsPaths = QCoreApplication::libraryPaths();
QCOMPARE(androidLibsPaths.size(), 1);
#endif
QCoreApplication::setLibraryPaths(QStringList());
QString absoluteBinPath = QFileInfo(binFolder).absoluteFilePath();
#ifndef Q_OS_ANDROID
QString pluginsPath = QFileInfo(binFolder).absoluteFilePath();
QFactoryLoader loader1(PluginInterface1_iid, "/nonexistent");
#else
QString pluginsPath = androidLibsPaths.first();
// On Android we still need to specify a valid suffix, because it's a part
// of a file name, not directory structure
const QString suffix = QLatin1Char('/') + QLatin1String(binFolderC);
QFactoryLoader loader1(PluginInterface1_iid, suffix);
#endif
// it shouldn't have scanned anything because we haven't given it a path yet
QVERIFY(loader1.metaData().isEmpty());
loader1.setExtraSearchPath(absoluteBinPath);
loader1.setExtraSearchPath(pluginsPath);
PluginInterface1 *plugin1 = qobject_cast<PluginInterface1 *>(loader1.instance(0));
QVERIFY2(plugin1,
qPrintable(QString::fromLatin1("Cannot load plugin '%1'")