summaryrefslogtreecommitdiffstats
path: root/tests/auto/cmake/test_import_plugins/CMakeLists.txt
blob: 5f6d629c20f824ed88a798425ef9e5a7bce5ce5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause

cmake_minimum_required(VERSION 3.16)

project(import_plugins_advanced)
enable_testing()

set(CMAKE_INCLUDE_CURRENT_DIR ON)

find_package(Qt6 COMPONENTS REQUIRED MockPlugins1 MockPlugins2)
# MockPlugins3 package is automatically found by the find_dependency call in
# QMock5PluginConfig.cmake which depends on MockPlugins3.
# QMock5Plugin itself is loaded by QtMockPlugins1Plugins.cmake, so via QtMockPlugins1Config.cmake.

function(create_test_executable target)
    cmake_parse_arguments(arg "FINALIZER_MODE;QT_WRAPPER" "" "ADD_EXECUTABLE_ARGS" ${ARGN})

    set(target_name_adjusted "${target}")
    if(arg_FINALIZER_MODE)
        set(target_name_adjusted "${target}_finalizer")
    endif()

    set(CHECK_FILE ${CMAKE_BINARY_DIR}/${target_name_adjusted}_check.cpp)

    set(EXPECTED_PLUGINS)
    foreach(_p ${arg_UNPARSED_ARGUMENTS})
        string(APPEND EXPECTED_PLUGINS "    \"${_p}\",\n")
    endforeach()
    configure_file("${CMAKE_SOURCE_DIR}/check.cpp.in" ${CHECK_FILE})

    set(add_executable_args ${target_name_adjusted} main.cpp ${CHECK_FILE}
        ${arg_ADD_EXECUTABLE_ARGS})

    if(arg_QT_WRAPPER)
        qt_add_executable(${add_executable_args})
    else()
        add_executable(${add_executable_args})
    endif()
    target_link_libraries(${target_name_adjusted} PRIVATE Qt6::MockPlugins1)
    add_test(test_${target_name_adjusted} ${target_name_adjusted})

    if(arg_FINALIZER_MODE)
        set(finalizer_mode_state "ENABLE")
    else()
        set(finalizer_mode_state "DISABLE")
    endif()

    qt_set_finalizer_mode(${target_name_adjusted} ${finalizer_mode_state} MODES static_plugins)
    set(target ${target_name_adjusted} PARENT_SCOPE)
endfunction()

# No call to qt_import_plugins() for the default case.
create_test_executable(default
    QMock1Plugin QMock2Plugin

    QMock3Plugin # TODO: Should not be linked based on .pro file, see QTBUG-93501
    ${import_mode}
)

# 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
    ${import_mode}
)
target_link_libraries(${target} PRIVATE Qt6::MockPlugins2)

# Check that both regular and finalizer mode plugin importing pulls in the same set of plugins.
# In regular mode, qt_finalize_target won't execute the finalizer plugin importing, because
# we opt out via qt_set_finalizer_mode(target DISABLE MODES static_plugins).
foreach(import_mode "" "FINALIZER_MODE")
    create_test_executable(manual QMock1Plugin QMock2Plugin QMock3Plugin QMock4Plugin
        ${import_mode})
    qt_import_plugins(${target}
        INCLUDE Qt6::QMock3Plugin Qt6::QMock4Plugin
    )
    qt_finalize_target(${target})

    create_test_executable(manual_genex QMock1Plugin QMock2Plugin QMock3Plugin ${import_mode})
    qt_import_plugins(${target}
        INCLUDE $<1:Qt6::QMock3Plugin> $<0:Qt6::QMock4Plugin>
    )
    qt_finalize_target(${target})

    create_test_executable(blacklist QMock1Plugin ${import_mode})
    qt_import_plugins(${target}
        EXCLUDE Qt6::QMock2Plugin Qt6::QMock3Plugin
    )
    qt_finalize_target(${target})

    create_test_executable(blacklist_genex QMock1Plugin ${import_mode})
    qt_import_plugins(${target}
        EXCLUDE $<1:Qt6::QMock2Plugin> $<1:Qt6::QMock3Plugin> $<0:Qt6::QMock1Plugin>
    )
    qt_finalize_target(${target})

    create_test_executable(override QMock3Plugin QMock4Plugin ${import_mode})
    qt_import_plugins(${target}
        INCLUDE_BY_TYPE mockplugin Qt6::QMock3Plugin Qt6::QMock4Plugin
    )
    qt_finalize_target(${target})

    create_test_executable(override_genex QMock3Plugin ${import_mode})
    qt_import_plugins(${target}
        INCLUDE_BY_TYPE mockplugin $<1:Qt6::QMock3Plugin> $<0:Qt6::QMock4Plugin>
    )
    qt_finalize_target(${target})

    create_test_executable(override_mix QMock2Plugin QMock3Plugin ${import_mode})
    qt_import_plugins(${target}
        INCLUDE Qt6::QMock2Plugin
        INCLUDE_BY_TYPE mockplugin Qt6::QMock3Plugin
    )
    qt_finalize_target(${target})

    if(NOT WIN32)
        # Compiling an empty static array fails on Windows.
        create_test_executable(none ${import_mode})
        qt_import_plugins(${target}
            EXCLUDE_BY_TYPE mockplugin
        )
        qt_finalize_target(${target})
    endif()

    create_test_executable(none_mix QMock3Plugin QMock4Plugin ${import_mode})
    qt_import_plugins(${target}
        INCLUDE Qt6::QMock3Plugin Qt6::QMock4Plugin
        EXCLUDE_BY_TYPE mockplugin
    )
    qt_finalize_target(${target})

    # 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 ${import_mode})
    qt_import_plugins(${target}
        INCLUDE_BY_TYPE mockplugin Qt6::QMock5Plugin
    )
    qt_finalize_target(${target})
endforeach()

# No call to qt_finalize_target() in finalizer mode means nothing will be
# linked.
if(NOT WIN32)
    # Compiling an empty static array fails on Windows.
    create_test_executable(default_finalizer_missing_import_call FINALIZER_MODE)
endif()

# Empty call to qt_import_plugins() in finalizer mode means default plugins are linked.
create_test_executable(default_finalizer
    QMock1Plugin QMock2Plugin
    QMock3Plugin # TODO: Should not be linked based on .pro file, see QTBUG-93501
    FINALIZER_MODE)
qt_import_plugins(${target})
qt_finalize_target(${target})

# Check that plugin importing with the qt_add_executable wrapper and manual finalization mode works.
create_test_executable(default_qt_add_executable_manually_finalized
    QMock1Plugin QMock2Plugin
    QMock3Plugin # TODO: Should not be linked based on .pro file, see QTBUG-93501
    FINALIZER_MODE QT_WRAPPER
    ADD_EXECUTABLE_ARGS MANUAL_FINALIZATION)
qt_finalize_target(${target})

# Check that plugin importing with automatic deferred finalization works when the CMake version is
# high enough.
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.19)
    create_test_executable(default_qt_add_executable_auto_finalized
        QMock1Plugin QMock2Plugin
        QMock3Plugin # TODO: Should not be linked based on .pro file, see QTBUG-93501
        FINALIZER_MODE QT_WRAPPER)
endif()