aboutsummaryrefslogtreecommitdiffstats
path: root/tools/qmlimportscanner/Qt5QmlImportScannerConfig.cmake.in
blob: 6cdfaf8f6fd6c8bbf261e218e47c09f69c7f9df8 (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
181
182
183
184
include(CMakeParseArguments)

function(QT5_IMPORT_QML_PLUGINS target)
!!IF !isEmpty(CMAKE_STATIC_TYPE)
    set(options)
    set(oneValueArgs \"PATH_TO_SCAN\")
    set(multiValueArgs)

    cmake_parse_arguments(arg \"${options}\" \"${oneValueArgs}\" \"${multiValueArgs}\" ${ARGN})
    if(NOT arg_PATH_TO_SCAN)
        set(arg_PATH_TO_SCAN \"${CMAKE_CURRENT_SOURCE_DIR}\")
    endif()

    # Find location of qmlimportscanner.
    find_package(Qt5 COMPONENTS Core)
!!IF isEmpty(CMAKE_BIN_DIR_IS_ABSOLUTE)
    set(tool_path
        \"${_qt5Core_install_prefix}/$${CMAKE_BIN_DIR}qmlimportscanner$$CMAKE_BIN_SUFFIX\")
!!ELSE
    set(tool_path \"$${CMAKE_BIN_DIR}qmlimportscanner$$CMAKE_BIN_SUFFIX\")
!!ENDIF
    if(NOT EXISTS \"${tool_path}\" )
        message(FATAL_ERROR \"The package \\\"Qt5QmlImportScannerConfig\\\" references the file
   \\\"${tool_path}\\\"
but this file does not exist.  Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty.
\")
    endif()

    # Find location of qml dir.
!!IF isEmpty(CMAKE_QML_DIR_IS_ABSOLUTE)
    set(qml_path \"${_qt5Core_install_prefix}/$${CMAKE_QML_DIR}\")
!!ELSE
    set(qml_path \"$${CMAKE_QML_DIR}\")
!!ENDIF

    # Small macro to avoid duplicating code in two different loops.
    macro(_qt5_QmlImportScanner_parse_entry)
        set(entry_name \"qml_import_scanner_import_${idx}\")
        cmake_parse_arguments(\"entry\"
                              \"\"
                              \"CLASSNAME;NAME;PATH;PLUGIN;RELATIVEPATH;TYPE;VERSION;\" \"\"
                              ${${entry_name}})
    endmacro()

    # Macro used to populate the dependency link flags for a certain configuriation (debug vs
    # release) of a plugin.
    macro(_qt5_link_to_QmlImportScanner_library_dependencies Plugin Configuration PluginLocation
                                                             IsDebugAndRelease)

        set_property(TARGET \"${Plugin}\" APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration})
        set(_imported_location \"${PluginLocation}\")
        _qt5_Core_check_file_exists(\"${_imported_location}\")
        set_target_properties(\"${Plugin}\" PROPERTIES
            \"IMPORTED_LOCATION_${Configuration}\" \"${_imported_location}\"
        )

        set(_static_deps
            ${_Qt5${entry_PLUGIN}_STATIC_${Configuration}_LIB_DEPENDENCIES}
        )

        if(NOT "${IsDebugAndRelease}")
            set(_genex_condition \"1\")
        else()
            if("${Configuration}" STREQUAL "DEBUG")
                set(_genex_condition \"$<CONFIG:Debug>\")
            else()
                set(_genex_condition \"$<NOT:$<CONFIG:Debug>>\")
            endif()
        endif()
        if(_static_deps)
            set(_static_deps_genex \"$<${_genex_condition}:${_static_deps}>\")
            target_link_libraries(${imported_target} INTERFACE \"${_static_deps_genex}\")
        endif()

        set(_static_link_flags \"${_Qt5${entry_PLUGIN}_STATIC_${Configuration}_LINK_FLAGS}\")
        if(NOT CMAKE_VERSION VERSION_LESS \"3.13\" AND _static_link_flags)
            set(_static_link_flags_genex \"$<${_genex_condition}:${_static_link_flags}>\")
            target_link_options(${imported_target} INTERFACE \"${_static_link_flags_genex}\")
        endif()
    endmacro()

    # Run qmlimportscanner and include the generated cmake file.
    set(qml_imports_file_path
        \"${CMAKE_CURRENT_BINARY_DIR}/Qt5_QmlPlugins_Imports_${target}.cmake\")

    message(STATUS \"Running qmlimportscanner to find used QML plugins. \")
    execute_process(COMMAND
                    \"${tool_path}\" \"${arg_PATH_TO_SCAN}\" -importPath \"${qml_path}\"
                    -cmake-output
                    OUTPUT_FILE \"${qml_imports_file_path}\")

    include(\"${qml_imports_file_path}\" OPTIONAL RESULT_VARIABLE qml_imports_file_path_found)
    if(NOT qml_imports_file_path_found)
        message(FATAL_ERROR \"Could not find ${qml_imports_file_path} which was supposed to be generated by qmlimportscanner.\")
    endif()

    # Parse the generate cmake file.
    # It is possible for the scanner to find no usage of QML, in which case the import count is 0.
    if(qml_import_scanner_imports_count)
        set(added_plugins \"\")
        foreach(idx RANGE \"${qml_import_scanner_imports_count}\")
            _qt5_QmlImportScanner_parse_entry()
            if(entry_PATH AND entry_PLUGIN)
                # Sometimes a plugin appears multiple times with different versions.
                # Make sure to process it only once.
                list(FIND added_plugins \"${entry_PLUGIN}\" _index)
                if(NOT _index EQUAL -1)
                    continue()
                endif()
                list(APPEND added_plugins \"${entry_PLUGIN}\")

                # Add an imported target that will contain the link libraries and link options read
                # from one plugin prl file. This target will point to the actual plugin and contain
                # static dependency libraries and link flags.
                # By creating a target for each qml plugin, CMake will take care of link flag
                # deduplication.
                set(imported_target \"${target}_QmlImport_${entry_PLUGIN}\")
                add_library(\"${imported_target}\" MODULE IMPORTED)
                target_link_libraries(\"${target}\" PRIVATE \"${imported_target}\")

                # Read static library dependencies from the plugin .prl file.
                # And then set the link flags to the library dependencies extracted from the .prl
                # file.
!!IF !isEmpty(CMAKE_RELEASE_TYPE)
                _qt5_Core_process_prl_file(
                    \"${entry_PATH}/$$QMAKE_PREFIX_STATICLIB${entry_PLUGIN}$${CMAKE_QML_PLUGIN_SUFFIX_RELEASE}.prl\" RELEASE
                    _Qt5${entry_PLUGIN}_STATIC_RELEASE_LIB_DEPENDENCIES
                    _Qt5${entry_PLUGIN}_STATIC_RELEASE_LINK_FLAGS
                )
                _qt5_link_to_QmlImportScanner_library_dependencies(
                    \"${imported_target}\"
                    RELEASE
                    \"${entry_PATH}/$$QMAKE_PREFIX_STATICLIB${entry_PLUGIN}$${CMAKE_QML_PLUGIN_SUFFIX_RELEASE}.$$QMAKE_EXTENSION_STATICLIB\"
                     $${CMAKE_DEBUG_AND_RELEASE})
!!ENDIF

!!IF !isEmpty(CMAKE_DEBUG_TYPE)
                _qt5_Core_process_prl_file(
                    \"${entry_PATH}/$$QMAKE_PREFIX_STATICLIB${entry_PLUGIN}$${CMAKE_QML_PLUGIN_SUFFIX_DEBUG}.prl\" DEBUG
                    _Qt5${entry_PLUGIN}_STATIC_DEBUG_LIB_DEPENDENCIES
                    _Qt5${entry_PLUGIN}_STATIC_DEBUG_LINK_FLAGS
                )
                _qt5_link_to_QmlImportScanner_library_dependencies(
                    \"${imported_target}\"
                    DEBUG
                    \"${entry_PATH}/$$QMAKE_PREFIX_STATICLIB${entry_PLUGIN}$${CMAKE_QML_PLUGIN_SUFFIX_DEBUG}.$$QMAKE_EXTENSION_STATICLIB\"
                     $${CMAKE_DEBUG_AND_RELEASE})
!!ENDIF
            endif()
        endforeach()

        # Generate content for plugin initialization cpp file.
        set(added_imports \"\")
        set(qt5_qml_import_cpp_file_content \"\")
        foreach(idx RANGE \"${qml_import_scanner_imports_count}\")
            _qt5_QmlImportScanner_parse_entry()
            if(entry_PLUGIN)
                if(entry_CLASSNAME)
                    list(FIND added_imports \"${entry_PLUGIN}\" _index)
                    if(_index EQUAL -1)
                        string(APPEND qt5_qml_import_cpp_file_content
                               \"Q_IMPORT_PLUGIN(${entry_CLASSNAME})\n\")
                        list(APPEND added_imports \"${entry_PLUGIN}\")
                    endif()
                else()
                    message(FATAL_ERROR
                            \"Plugin ${entry_PLUGIN} is missing a classname entry, please add one to the qmldir file.\")
                endif()
            endif()
        endforeach()

        # Write to the generated file, and include it as a source for the given target.
        set(generated_import_cpp_path
            \"${CMAKE_CURRENT_BINARY_DIR}/Qt5_QmlPlugins_Imports_${target}.cpp\")
        configure_file(\"${Qt5QmlImportScanner_DIR}/Qt5QmlImportScannerTemplate.cpp.in\"
                       \"${generated_import_cpp_path}\"
                       @ONLY)
        target_sources(${target} PRIVATE \"${generated_import_cpp_path}\")
    endif()
!!ENDIF // !isEmpty(CMAKE_STATIC_TYPE)
endfunction()