CMake: Resurrect test_import_plugins cmake build tests
Now that we run tests for static Qt builds in the CI, it makes sense to restore the CMake build tests that check that static plugin importing works correctly. Resurrect the previously commented out test_import_plugins project and port the mockplugins qmake projects to CMake. mockplugins is a CMake project that uses the internal Qt CMake API to build and install some Qt modules and plugins. test_import_plugins depends on that test (via a CMake fixture) to build public projects that use those plugins. The installation of the mockplugins modules pollutes the Qt install prefix, but in the CI that only happens on the test VM, which means the release packages are not affected. Locally on a developer machine the Qt install path will be polluted, but it's not that much of a big deal. We could try and address that in a future change by using the QT_ADDITIONAL_PACKAGES_PREFIX_PATH functionality added for Conan to allow the installation of Qt packages into a non-standard prefix. Task-number: QTBUG-87580 Task-number: QTBUG-92933 Change-Id: I0841064a60a5ffba5118640d3197527a38ba6c30 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
parent
22a992cb12
commit
3a62f9e0c9
@ -803,10 +803,13 @@ function(qt6_import_plugins target)
|
||||
|
||||
# Check if passed plugin target name is a version-less one, and make a version-full
|
||||
# one.
|
||||
set_property(TARGET "${target}" APPEND PROPERTY "QT_PLUGINS_${_current_type}" "${_arg}")
|
||||
_qt_get_plugin_name_with_version("${_arg}" qt_plugin_with_version)
|
||||
if(TARGET "${_arg}" OR TARGET "${qt_plugin_with_version}")
|
||||
set_property(TARGET "${target}" APPEND PROPERTY "QT_PLUGINS_${_current_type}" "${_arg}")
|
||||
else()
|
||||
|
||||
# TODO: Do we really need this check? We didn't have it in Qt5, and plugin targets
|
||||
# wrapped in genexes end up causing warnings, but we explicitly use GENEX_EVAL to
|
||||
# support them.
|
||||
if(NOT TARGET "${_arg}" AND NOT TARGET "${qt_plugin_with_version}")
|
||||
message("Warning: plug-in ${_arg} is not known to the current Qt installation.")
|
||||
endif()
|
||||
endif()
|
||||
|
@ -221,8 +221,30 @@ if(NOT NO_WIDGETS)
|
||||
_qt_internal_test_expect_pass(test_QTBUG-63422)
|
||||
endif()
|
||||
|
||||
# FIXME: Needs porting of the qmake .pro files to create the modules and plugins in Qt6 CMake land.
|
||||
# _qt_internal_test_expect_pass(test_import_plugins BINARY ${CMAKE_CTEST_COMMAND})
|
||||
# Find main Qt installation location and bin dir.
|
||||
if(QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX)
|
||||
set(qt_install_prefix "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}")
|
||||
elseif(QT6_INSTALL_PREFIX)
|
||||
set(qt_install_prefix "${QT6_INSTALL_PREFIX}")
|
||||
endif()
|
||||
if(INSTALL_BINDIR)
|
||||
set(qt_install_bin_dir "${INSTALL_BINDIR}")
|
||||
elseif(QT6_INSTALL_BINS)
|
||||
set(qt_install_bin_dir "${QT6_INSTALL_BINS}")
|
||||
endif()
|
||||
|
||||
# Test building and installing a few dummy Qt modules and plugins.
|
||||
_qt_internal_test_expect_pass(mockplugins
|
||||
BINARY "${CMAKE_COMMAND}"
|
||||
BINARY_ARGS
|
||||
"-DQT_BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR}/mockplugins"
|
||||
-P "${qt_install_prefix}/${qt_install_bin_dir}/qt-cmake-private-install.cmake")
|
||||
set_tests_properties(mockplugins PROPERTIES FIXTURES_SETUP build_mockplugins)
|
||||
|
||||
# Test importing the plugins built in the project above.
|
||||
_qt_internal_test_expect_pass(test_import_plugins BINARY ${CMAKE_CTEST_COMMAND} BINARY_ARGS -V)
|
||||
set_tests_properties(test_import_plugins PROPERTIES FIXTURES_REQUIRED build_mockplugins)
|
||||
|
||||
_qt_internal_test_expect_pass(test_versionless_targets)
|
||||
|
||||
_qt_internal_test_expect_pass(test_add_resources_binary_generated
|
||||
|
1
tests/auto/cmake/mockplugins/.cmake.conf
Normal file
1
tests/auto/cmake/mockplugins/.cmake.conf
Normal file
@ -0,0 +1 @@
|
||||
set(QT_REPO_MODULE_VERSION "6.2.0")
|
32
tests/auto/cmake/mockplugins/CMakeLists.txt
Normal file
32
tests/auto/cmake/mockplugins/CMakeLists.txt
Normal file
@ -0,0 +1,32 @@
|
||||
# Generated from qtsvg.pro.
|
||||
|
||||
cmake_minimum_required(VERSION 3.15.0)
|
||||
|
||||
include(.cmake.conf)
|
||||
project(QtMockPlugins
|
||||
VERSION "${QT_REPO_MODULE_VERSION}"
|
||||
DESCRIPTION "Qt MockPlugins Libraries"
|
||||
HOMEPAGE_URL "https://qt.io/"
|
||||
LANGUAGES CXX C
|
||||
)
|
||||
|
||||
# Make sure we only use latest private CMake API, aka no compatibility wrappers.
|
||||
set(QT_NO_INTERNAL_COMPATIBILITY_FUNCTIONS TRUE)
|
||||
|
||||
find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS BuildInternals Core)
|
||||
find_package(Qt6 ${PROJECT_VERSION} QUIET CONFIG OPTIONAL_COMPONENTS Gui Widgets Xml)
|
||||
|
||||
qt_build_repo_begin()
|
||||
|
||||
add_subdirectory(mockplugins1)
|
||||
add_subdirectory(mockplugins2)
|
||||
add_subdirectory(mockplugins3)
|
||||
|
||||
add_subdirectory(mock1plugin)
|
||||
add_subdirectory(mock2plugin)
|
||||
add_subdirectory(mock3plugin)
|
||||
add_subdirectory(mock4plugin)
|
||||
add_subdirectory(mock5plugin)
|
||||
add_subdirectory(mock6plugin)
|
||||
|
||||
qt_build_repo_end()
|
9
tests/auto/cmake/mockplugins/mock1plugin/CMakeLists.txt
Normal file
9
tests/auto/cmake/mockplugins/mock1plugin/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
qt_internal_add_plugin(QMock1Plugin
|
||||
CLASS_NAME QMock1Plugin
|
||||
TYPE mockplugin
|
||||
SOURCES
|
||||
qmock1plugin.cpp qmock1plugin.h
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Core
|
||||
Qt::MockPlugins1
|
||||
)
|
9
tests/auto/cmake/mockplugins/mock2plugin/CMakeLists.txt
Normal file
9
tests/auto/cmake/mockplugins/mock2plugin/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
qt_internal_add_plugin(QMock2Plugin
|
||||
CLASS_NAME QMock2Plugin
|
||||
TYPE mockplugin
|
||||
SOURCES
|
||||
qmock2plugin.cpp qmock2plugin.h
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Core
|
||||
Qt::MockPlugins1
|
||||
)
|
9
tests/auto/cmake/mockplugins/mock3plugin/CMakeLists.txt
Normal file
9
tests/auto/cmake/mockplugins/mock3plugin/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
qt_internal_add_plugin(QMock3Plugin
|
||||
CLASS_NAME QMock3Plugin
|
||||
TYPE mockplugin
|
||||
SOURCES
|
||||
qmock3plugin.cpp qmock3plugin.h
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Core
|
||||
Qt::MockPlugins1
|
||||
)
|
10
tests/auto/cmake/mockplugins/mock4plugin/CMakeLists.txt
Normal file
10
tests/auto/cmake/mockplugins/mock4plugin/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
qt_internal_add_plugin(QMock4Plugin
|
||||
CLASS_NAME QMock4Plugin
|
||||
TYPE mockplugin
|
||||
DEFAULT_IF FALSE
|
||||
SOURCES
|
||||
qmock4plugin.cpp qmock4plugin.h
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Core
|
||||
Qt::MockPlugins1
|
||||
)
|
10
tests/auto/cmake/mockplugins/mock5plugin/CMakeLists.txt
Normal file
10
tests/auto/cmake/mockplugins/mock5plugin/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
qt_internal_add_plugin(QMock5Plugin
|
||||
CLASS_NAME QMock5Plugin
|
||||
TYPE mockplugin
|
||||
DEFAULT_IF FALSE
|
||||
SOURCES
|
||||
qmock5plugin.cpp qmock5plugin.h
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Core
|
||||
Qt::MockPlugins3
|
||||
)
|
9
tests/auto/cmake/mockplugins/mock6plugin/CMakeLists.txt
Normal file
9
tests/auto/cmake/mockplugins/mock6plugin/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
qt_internal_add_plugin(QMock6Plugin
|
||||
CLASS_NAME QMock6Plugin
|
||||
TYPE mockauxplugin
|
||||
SOURCES
|
||||
qmock6plugin.cpp qmock6plugin.h
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Core
|
||||
Qt::MockPlugins3
|
||||
)
|
9
tests/auto/cmake/mockplugins/mockplugins1/CMakeLists.txt
Normal file
9
tests/auto/cmake/mockplugins/mockplugins1/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
qt_internal_add_module(MockPlugins1
|
||||
PLUGIN_TYPES mockplugin
|
||||
SOURCES
|
||||
fake.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Core
|
||||
)
|
@ -0,0 +1,2 @@
|
||||
# This is needed so that MODULE_PLUGIN_TYPES property is set on the exported target.
|
||||
# Fun times.
|
8
tests/auto/cmake/mockplugins/mockplugins2/CMakeLists.txt
Normal file
8
tests/auto/cmake/mockplugins/mockplugins2/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
qt_internal_add_module(MockPlugins2
|
||||
SOURCES
|
||||
fake.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Core
|
||||
)
|
9
tests/auto/cmake/mockplugins/mockplugins3/CMakeLists.txt
Normal file
9
tests/auto/cmake/mockplugins/mockplugins3/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
qt_internal_add_module(MockPlugins3
|
||||
PLUGIN_TYPES mockauxplugin
|
||||
SOURCES
|
||||
fake.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Core
|
||||
)
|
@ -0,0 +1,2 @@
|
||||
# This is needed so that MODULE_PLUGIN_TYPES property is set on the exported target.
|
||||
# Fun times.
|
@ -1,4 +1,3 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
project(import_plugins_advanced)
|
||||
@ -6,26 +5,9 @@ enable_testing()
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/FindPackageHints.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/FindPackageHints.cmake")
|
||||
endif()
|
||||
|
||||
# Need to find Qt5Core explicitly because the MockPlugins1 and MockPlugins2 config files
|
||||
# are in a different directory (the source dir) when doing a standalone tests build,
|
||||
# whereas Core is in the installed directory, and due to NO_DEFAULT_PATH being used
|
||||
# for the Core dependency call in Qt5MockPlugins, Core would not be found in the source
|
||||
# dir.
|
||||
find_package(Qt5 COMPONENTS Core REQUIRED HINTS ${Qt5Tests_PREFIX_PATH})
|
||||
get_target_property(qt_is_static Qt5::Core TYPE)
|
||||
|
||||
# For a similar reason, we need to find the MockPlugins packages not via COMPONENTS argument,
|
||||
# but directly, because the location of Qt5Config.cmake is in the installed dir, while
|
||||
# the MockPlugins are in the source dir, and Qt5Config only looks for packages relative
|
||||
# to its own location.
|
||||
# The packages are still successfuly found, because the CMAKE_PREFIX_PATH populated by qmake
|
||||
# contains both the installed Qt dir, and the Qt source dir.
|
||||
find_package(Qt5MockPlugins1 REQUIRED HINTS ${Qt5Tests_PREFIX_PATH})
|
||||
find_package(Qt5MockPlugins2 REQUIRED HINTS ${Qt5Tests_PREFIX_PATH})
|
||||
find_package(Qt6 COMPONENTS REQUIRED MockPlugins1 MockPlugins2)
|
||||
# MockPlugins3 is automatically find_dependency'd by QMock5Plugin which depends on MockPlugins3.
|
||||
# QMock5Plugin itself is loaded by QtMockPlugins1Plugins.cmake.
|
||||
|
||||
function(create_test_executable TARGET_NAME)
|
||||
set(CHECK_FILE ${CMAKE_BINARY_DIR}/${TARGET_NAME}_check.cpp)
|
||||
@ -37,75 +19,87 @@ function(create_test_executable TARGET_NAME)
|
||||
configure_file("${CMAKE_SOURCE_DIR}/check.cpp.in" ${CHECK_FILE})
|
||||
|
||||
add_executable(${TARGET_NAME} main.cpp ${CHECK_FILE})
|
||||
target_link_libraries(${TARGET_NAME} Qt5::MockPlugins1)
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE Qt6::MockPlugins1)
|
||||
add_test(test_${TARGET_NAME} ${TARGET_NAME})
|
||||
endfunction()
|
||||
|
||||
create_test_executable(default QMock1Plugin QMock2Plugin)
|
||||
# No call to qt5_import_plugins() for the default
|
||||
# No call to qt_import_plugins() for the default case.
|
||||
create_test_executable(default
|
||||
QMock1Plugin QMock2Plugin
|
||||
|
||||
# TODO This test is known to fail because CMake currently doesn't have a way to
|
||||
# implement its own equivalent of the PLUGIN_EXTENDS mechanism at generate-
|
||||
# time (meaning a library only gets linked if a set of other libraries are
|
||||
# *also* linked.) CMake 3.14 or beyond may have such a mechanism, but until
|
||||
# then, this test is expected to fail, because QMock3Plugin is not being
|
||||
# linked even though MockPlugins2 is present.
|
||||
create_test_executable(default_link QMock1Plugin QMock2Plugin QMock3Plugin)
|
||||
target_link_libraries(default_link Qt5::MockPlugins2)
|
||||
set_property(TEST test_default_link PROPERTY DISABLED 1)
|
||||
# No call to qt5_import_plugins() for the default
|
||||
QMock3Plugin # TODO: Should not be linked based on .pro file, see QTBUG-93501
|
||||
)
|
||||
|
||||
# No call to qt_import_plugins() for the default_link case.
|
||||
create_test_executable(default_link QMock1Plugin QMock2Plugin
|
||||
|
||||
# TODO: in qmake QMock3Plugin should only be linked if the executable depends on MockPlugins2
|
||||
# module (based on .pro file PLUGIN_EXTENDS). Here it's accidentally linked because
|
||||
# we're missing PLUGIN_EXTENDS information in CMake land. Thus it's considered
|
||||
# a default plugin which is linked regardless of whether MockPlugins2 is linked.
|
||||
# It's possible the qmake behavior is also wrong, because the qmake qt5 test seems to
|
||||
# expect to link the plugin if both MockPlugins1 AND MockPlugins2 are linked, but qt.pf
|
||||
# suggests that MockPlugins1 OR MockPlugins2 is sufficient to link the plugin, not both.
|
||||
# See QTBUG-93501
|
||||
QMock3Plugin
|
||||
)
|
||||
target_link_libraries(default_link PRIVATE Qt6::MockPlugins2)
|
||||
|
||||
create_test_executable(manual QMock1Plugin QMock2Plugin QMock3Plugin QMock4Plugin)
|
||||
qt5_import_plugins(manual
|
||||
INCLUDE Qt5::QMock3Plugin Qt5::QMock4Plugin
|
||||
qt_import_plugins(manual
|
||||
INCLUDE Qt6::QMock3Plugin Qt6::QMock4Plugin
|
||||
)
|
||||
|
||||
create_test_executable(manual_genex QMock1Plugin QMock2Plugin QMock3Plugin)
|
||||
qt5_import_plugins(manual_genex
|
||||
INCLUDE $<1:Qt5::QMock3Plugin> $<0:Qt5::QMock4Plugin>
|
||||
qt_import_plugins(manual_genex
|
||||
INCLUDE $<1:Qt6::QMock3Plugin> $<0:Qt6::QMock4Plugin>
|
||||
)
|
||||
|
||||
create_test_executable(blacklist QMock1Plugin)
|
||||
qt5_import_plugins(blacklist
|
||||
EXCLUDE Qt5::QMock2Plugin Qt5::QMock3Plugin
|
||||
qt_import_plugins(blacklist
|
||||
EXCLUDE Qt6::QMock2Plugin Qt6::QMock3Plugin
|
||||
)
|
||||
|
||||
create_test_executable(blacklist_genex QMock1Plugin)
|
||||
qt5_import_plugins(blacklist_genex
|
||||
EXCLUDE $<1:Qt5::QMock2Plugin> $<1:Qt5::QMock3Plugin> $<0:Qt5::QMock1Plugin>
|
||||
qt_import_plugins(blacklist_genex
|
||||
EXCLUDE $<1:Qt6::QMock2Plugin> $<1:Qt6::QMock3Plugin> $<0:Qt6::QMock1Plugin>
|
||||
)
|
||||
|
||||
create_test_executable(override QMock3Plugin QMock4Plugin)
|
||||
qt5_import_plugins(override
|
||||
INCLUDE_BY_TYPE mockplugin Qt5::QMock3Plugin Qt5::QMock4Plugin
|
||||
qt_import_plugins(override
|
||||
INCLUDE_BY_TYPE mockplugin Qt6::QMock3Plugin Qt6::QMock4Plugin
|
||||
)
|
||||
|
||||
create_test_executable(override_genex QMock3Plugin)
|
||||
qt5_import_plugins(override_genex
|
||||
INCLUDE_BY_TYPE mockplugin $<1:Qt5::QMock3Plugin> $<0:Qt5::QMock4Plugin>
|
||||
qt_import_plugins(override_genex
|
||||
INCLUDE_BY_TYPE mockplugin $<1:Qt6::QMock3Plugin> $<0:Qt6::QMock4Plugin>
|
||||
)
|
||||
get_target_property(prop_plugs override_genex QT_PLUGINS)
|
||||
get_target_property(prop_types override_genex QT_PLUGINS_mockplugin)
|
||||
|
||||
create_test_executable(override_mix QMock2Plugin QMock3Plugin)
|
||||
qt5_import_plugins(override_mix
|
||||
INCLUDE Qt5::QMock2Plugin
|
||||
INCLUDE_BY_TYPE mockplugin Qt5::QMock3Plugin
|
||||
qt_import_plugins(override_mix
|
||||
INCLUDE Qt6::QMock2Plugin
|
||||
INCLUDE_BY_TYPE mockplugin Qt6::QMock3Plugin
|
||||
)
|
||||
|
||||
if(NOT WIN32)
|
||||
# Compiling an empty static array fails on Windows.
|
||||
create_test_executable(none)
|
||||
qt5_import_plugins(none
|
||||
qt_import_plugins(none
|
||||
EXCLUDE_BY_TYPE mockplugin
|
||||
)
|
||||
endif()
|
||||
|
||||
create_test_executable(none_mix QMock3Plugin QMock4Plugin)
|
||||
qt5_import_plugins(none_mix
|
||||
INCLUDE Qt5::QMock3Plugin Qt5::QMock4Plugin
|
||||
qt_import_plugins(none_mix
|
||||
INCLUDE Qt6::QMock3Plugin Qt6::QMock4Plugin
|
||||
EXCLUDE_BY_TYPE mockplugin
|
||||
)
|
||||
|
||||
# QMock5Plugin links against the Qt::MockPlugins3 module, which provides the default plugin
|
||||
# QMock6Plugin which is why it is pulled in.
|
||||
create_test_executable(recursive QMock5Plugin QMock6Plugin)
|
||||
qt5_import_plugins(recursive
|
||||
INCLUDE_BY_TYPE mockplugin Qt5::QMock5Plugin
|
||||
qt_import_plugins(recursive
|
||||
INCLUDE_BY_TYPE mockplugin Qt6::QMock5Plugin
|
||||
)
|
||||
|
@ -5,4 +5,4 @@ QString expectedPlugins[] = {
|
||||
@EXPECTED_PLUGINS@
|
||||
};
|
||||
|
||||
std::size_t numExpectedPlugins = sizeof(expectedPlugins) / sizeof(numExpectedPlugins);
|
||||
std::size_t numExpectedPlugins = sizeof(expectedPlugins) / sizeof(*expectedPlugins);
|
||||
|
@ -77,7 +77,7 @@ int main(int argc, char **argv)
|
||||
std::cerr << "Loaded plugins do not match what was expected!" << std::endl
|
||||
<< "Expected plugins:" << std::endl;
|
||||
|
||||
QList<QString> expectedPluginList = expectedPluginSet.toList();
|
||||
QList<QString> expectedPluginList = expectedPluginSet.values();
|
||||
expectedPluginList.sort();
|
||||
for (QString plugin : expectedPluginList) {
|
||||
std::cerr << (actualPluginSet.contains(plugin) ? " " : "- ")
|
||||
@ -86,7 +86,7 @@ int main(int argc, char **argv)
|
||||
|
||||
std::cerr << std::endl << "Actual plugins:" << std::endl;
|
||||
|
||||
QList<QString> actualPluginList = actualPluginSet.toList();
|
||||
QList<QString> actualPluginList = actualPluginSet.values();
|
||||
actualPluginList.sort();
|
||||
for (QString plugin : actualPluginList) {
|
||||
std::cerr << (expectedPluginSet.contains(plugin) ? " " : "+ ")
|
||||
|
Loading…
Reference in New Issue
Block a user