CMake: Add Qt6 forward compatible CMake API and targets

Create Qt:: versionless targets for libraries and tools. So
Qt::Core will link to Qt5::Core.

Add additional feature properties to targets, with the same name
they have in Qt6: QT_ENABLED_PUBLIC_FEATURES,
QT_DISABLED_PUBLIC_FEATURES, QT_ENABLED_PRIVATE_FEATURES,
QT_DISABLED_PRIVATE_FEATURES, to be forward-compatible with Qt6.
Prefix properties with INTERFACE_ for interface libraries.

Create functions with no major version in their prefix, so qt_foo
instead of qt5_foo.
The non-versioned functions will call the versioned functions,
depending on the value of QT_DEFAULT_MAJOR_VERSION, which can be
set by an application developer before finding the Qt package.

Set QT_DEFAULT_MAJOR_VERSION to 5 if the value has not been defined
in the current scope.

Application developers can set QT_NO_CREATE_VERSIONLESS_FUNCTIONS to
TRUE before calling find_package(Qt5) to suppress creation of the
non-versioned functions.

Application developers can set QT_NO_CREATE_VERSIONLESS_TARGETS to
TRUE before calling find_package(Qt5) to suppress creation of the
non-versioned targets.

Setting these can be useful when both find_package(Qt5) and
find_package(Qt6) are in the same project.
If none of these are set by the user, then the first find_package(Qt5)
will create versionless targets with the major version being "5",
which means the second find_package(Qt6) will not create versionless
targets.

Handle versionless plugin names in qt_import_plugins, so both
Qt::QCocoaIntegrationPlugin and Qt5/6::QCocoaIntegrationPlugin
are recognized by the function.

Allow specifying multiple types in EXCLUDE_BY_TYPE in
qt_import_plugins, to be consitent with the Qt 6 version.

Make sure to set the QT_PLUGIN_CLASS_NAME property to compatible with
Qt 6.

Task-number: QTBUG-74137
Task-number: QTBUG-80477
Change-Id: Ib89d090ea6f7794d7debd64f03f29da963a17ca7
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
bb10
Alexandru Croitor 2019-12-02 18:03:47 +01:00
parent f3d3c095a6
commit e9a797799e
9 changed files with 219 additions and 7 deletions

View File

@ -176,7 +176,7 @@ contains(CONFIG, plugin) {
list_plugin_extends =
for (p, PLUGIN_EXTENDS) {
m = $$cmakeModuleName($$p)
list_plugin_extends += Qt5::$$m
list_plugin_extends += Qt::$$m
}
CMAKE_PLUGIN_EXTENDS = $$join(list_plugin_extends, ";")
}
@ -291,6 +291,10 @@ CMAKE_INTERFACE_MODULE_DEPS = $$join(aux_mod_deps, ";")
CMAKE_INTERFACE_QT5_MODULE_DEPS = $$join(aux_lib_deps, ";")
CMAKE_MODULE_PLUGIN_TYPES = $$join(QT.$${MODULE}.plugin_types, ";")
# Interface libraries have to have all properties starting with "INTERFACE_".
CMAKE_FEATURE_PROPERTY_PREFIX = ""
equals(TEMPLATE, aux): CMAKE_FEATURE_PROPERTY_PREFIX = "INTERFACE_"
mac {
!isEmpty(CMAKE_STATIC_TYPE) {
CMAKE_LIB_FILE_LOCATION_DEBUG = lib$${CMAKE_QT_STEM}_debug.a

View File

@ -406,6 +406,15 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME})
add_library(Qt5::$${CMAKE_MODULE_NAME} SHARED IMPORTED)
!!ENDIF
!!ENDIF
# Add a versionless target, for compatibility with Qt6.
if(NOT \"${QT_NO_CREATE_VERSIONLESS_TARGETS}\" AND NOT TARGET Qt::$${CMAKE_MODULE_NAME})
add_library(Qt::$${CMAKE_MODULE_NAME} INTERFACE IMPORTED)
set_target_properties(Qt::$${CMAKE_MODULE_NAME} PROPERTIES
INTERFACE_LINK_LIBRARIES \"Qt5::$${CMAKE_MODULE_NAME}\"
)
endif()
!!IF !equals(TEMPLATE, aux)
!!IF !isEmpty(CMAKE_BUILD_IS_FRAMEWORK)
set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} PROPERTY FRAMEWORK 1)
@ -420,6 +429,20 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME})
set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} PROPERTY INTERFACE_QT_ENABLED_FEATURES $$join(QT.$${MODULE}.enabled_features, ";"))
set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} PROPERTY INTERFACE_QT_DISABLED_FEATURES $$join(QT.$${MODULE}.disabled_features, ";"))
# Qt 6 forward compatible properties.
set_property(TARGET Qt5::$${CMAKE_MODULE_NAME}
PROPERTY $${CMAKE_FEATURE_PROPERTY_PREFIX}QT_ENABLED_PUBLIC_FEATURES
$$join(QT.$${MODULE}.enabled_features, ";"))
set_property(TARGET Qt5::$${CMAKE_MODULE_NAME}
PROPERTY $${CMAKE_FEATURE_PROPERTY_PREFIX}QT_DISABLED_PUBLIC_FEATURES
$$join(QT.$${MODULE}.disabled_features, ";"))
set_property(TARGET Qt5::$${CMAKE_MODULE_NAME}
PROPERTY $${CMAKE_FEATURE_PROPERTY_PREFIX}QT_ENABLED_PRIVATE_FEATURES
$$join(QT.$${MODULE}_private.enabled_features, ";"))
set_property(TARGET Qt5::$${CMAKE_MODULE_NAME}
PROPERTY $${CMAKE_FEATURE_PROPERTY_PREFIX}QT_DISABLED_PRIVATE_FEATURES
$$join(QT.$${MODULE}_private.disabled_features, ";"))
set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} PROPERTY INTERFACE_QT_PLUGIN_TYPES \"$${CMAKE_MODULE_PLUGIN_TYPES}\")
set(_Qt5$${CMAKE_MODULE_NAME}_PRIVATE_DIRS_EXIST TRUE)
@ -443,6 +466,14 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME})
set_property(TARGET Qt5::$${CMAKE_MODULE_NAME}Private PROPERTY
INTERFACE_LINK_LIBRARIES Qt5::$${CMAKE_MODULE_NAME} ${_Qt5$${CMAKE_MODULE_NAME}_PRIVATEDEPS}
)
# Add a versionless target, for compatibility with Qt6.
if(NOT \"${QT_NO_CREATE_VERSIONLESS_TARGETS}\" AND NOT TARGET Qt::$${CMAKE_MODULE_NAME}Private)
add_library(Qt::$${CMAKE_MODULE_NAME}Private INTERFACE IMPORTED)
set_target_properties(Qt::$${CMAKE_MODULE_NAME}Private PROPERTIES
INTERFACE_LINK_LIBRARIES \"Qt5::$${CMAKE_MODULE_NAME}Private\"
)
endif()
endif()
!!IF !equals(TEMPLATE, aux)

View File

@ -75,19 +75,30 @@ endif()
set(_user_specified_genex
\"$<IN_LIST:Qt5::$$CMAKE_PLUGIN_NAME,${_manual_plugins_genex};${_plugin_type_genex}>\"
)
set(_user_specified_genex_versionless
\"$<IN_LIST:Qt::$$CMAKE_PLUGIN_NAME,${_manual_plugins_genex};${_plugin_type_genex}>\"
)
string(CONCAT _plugin_genex
\"$<$<OR:\"
# Add this plugin if it\'s in the list of manual plugins or plugins for the type
# Add this plugin if it\'s in the list of manually specified plugins or in the list of
# explicitly included plugin types.
\"${_user_specified_genex},\"
# Add this plugin if the list of plugins for the type is empty, the PLUGIN_EXTENDS
# is either empty or equal to the module name, and the user hasn\'t blacklisted it
\"${_user_specified_genex_versionless},\"
# Add this plugin if all of the following are true:
# 1) the list of explicitly included plugin types is empty
# 2) the QT_PLUGIN_EXTENDS property for the plugin is empty or equal to the current
# module name
# 3) the user hasn\'t explicitly excluded the plugin.
\"$<AND:\"
\"$<STREQUAL:${_plugin_type_genex},>,\"
\"$<OR:\"
\"$<STREQUAL:$<TARGET_PROPERTY:Qt5::$${CMAKE_PLUGIN_NAME},QT_PLUGIN_EXTENDS>,Qt5::$${CMAKE_MODULE_NAME}>,\"
# FIXME: The value of CMAKE_MODULE_NAME seems to be wrong (e.g for Svg plugin
# it should be Qt::Svg instead of Qt::Gui).
\"$<STREQUAL:$<TARGET_PROPERTY:Qt5::$${CMAKE_PLUGIN_NAME},QT_PLUGIN_EXTENDS>,Qt::$${CMAKE_MODULE_NAME}>,\"
\"$<STREQUAL:$<TARGET_PROPERTY:Qt5::$${CMAKE_PLUGIN_NAME},QT_PLUGIN_EXTENDS>,>\"
\">,\"
\"$<NOT:$<IN_LIST:Qt5::$${CMAKE_PLUGIN_NAME},${_no_plugins_genex}>>\"
\"$<NOT:$<IN_LIST:Qt5::$${CMAKE_PLUGIN_NAME},${_no_plugins_genex}>>,\"
\"$<NOT:$<IN_LIST:Qt::$${CMAKE_PLUGIN_NAME},${_no_plugins_genex}>>\"
\">\"
\">:Qt5::$$CMAKE_PLUGIN_NAME>\"
)
@ -100,3 +111,4 @@ set_property(TARGET Qt5::$${CMAKE_PLUGIN_NAME} APPEND PROPERTY INTERFACE_LINK_LI
!!ENDIF
set_property(TARGET Qt5::$${CMAKE_PLUGIN_NAME} PROPERTY QT_PLUGIN_TYPE \"$$CMAKE_PLUGIN_TYPE\")
set_property(TARGET Qt5::$${CMAKE_PLUGIN_NAME} PROPERTY QT_PLUGIN_EXTENDS \"$$CMAKE_PLUGIN_EXTENDS\")
set_property(TARGET Qt5::$${CMAKE_PLUGIN_NAME} PROPERTY QT_PLUGIN_CLASS_NAME \"$$CMAKE_PLUGIN_NAME\")

View File

@ -1,3 +1,6 @@
if(NOT DEFINED QT_DEFAULT_MAJOR_VERSION)
set(QT_DEFAULT_MAJOR_VERSION 5)
endif()
if (NOT TARGET Qt5::qmake)
add_executable(Qt5::qmake IMPORTED)
@ -177,3 +180,24 @@ if (ANDROID_PLATFORM)
endif()
_qt5_Core_check_file_exists(${_Qt5CTestMacros})
# Create versionless tool targets.
foreach(__qt_tool qmake moc rcc)
if(NOT \"${QT_NO_CREATE_VERSIONLESS_TARGETS}\" AND NOT TARGET Qt::${__qt_tool}
AND TARGET Qt5::${__qt_tool})
add_executable(Qt::${__qt_tool} IMPORTED)
get_target_property(__qt_imported_location Qt5::${__qt_tool} IMPORTED_LOCATION)
set_target_properties(Qt::${__qt_tool}
PROPERTIES IMPORTED_LOCATION \"${__qt_imported_location}\")
endif()
endforeach()
!!IF !isEmpty(CMAKE_WINDOWS_BUILD)
# Add a versionless target for WinMain.
if(NOT \"${QT_NO_CREATE_VERSIONLESS_TARGETS}\" AND NOT TARGET Qt::WinMain)
add_library(Qt::WinMain INTERFACE IMPORTED)
set_target_properties(Qt::WinMain PROPERTIES
INTERFACE_LINK_LIBRARIES \"Qt5::WinMain\"
)
endif()
!!ENDIF

View File

@ -157,6 +157,16 @@ function(qt5_generate_moc infile outfile )
qt5_create_moc_command(${abs_infile} ${_outfile} "${moc_flags}" "" "${moc_target}" "")
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
function(qt_generate_moc)
if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
qt5_generate_moc(${ARGV})
elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
qt6_generate_moc(${ARGV})
endif()
endfunction()
endif()
# qt5_wrap_cpp(outfiles inputfile ... )
@ -184,6 +194,17 @@ function(qt5_wrap_cpp outfiles )
set(${outfiles} ${${outfiles}} PARENT_SCOPE)
endfunction()
# This will override the CMake upstream command, because that one is for Qt 3.
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
function(qt_wrap_cpp outfiles)
if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
qt5_wrap_cpp("${outfiles}" ${ARGN})
elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
qt6_wrap_cpp("${outfiles}" ${ARGN})
endif()
set("${outfiles}" "${${outfiles}}" PARENT_SCOPE)
endfunction()
endif()
# _qt5_parse_qrc_file(infile _out_depends _rc_depends)
@ -255,6 +276,16 @@ function(qt5_add_binary_resources target )
add_custom_target(${target} ALL DEPENDS ${rcc_destination})
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
function(qt_add_binary_resources)
if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
qt5_add_binary_resources(${ARGV})
elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
qt6_add_binary_resources(${ARGV})
endif()
endfunction()
endif()
# qt5_add_resources(outfiles inputfile ... )
@ -293,6 +324,18 @@ function(qt5_add_resources outfiles )
set(${outfiles} ${${outfiles}} PARENT_SCOPE)
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
function(qt_add_resources outfiles)
if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
qt5_add_resources("${outfiles}" ${ARGN})
elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
qt6_add_resources("${outfiles}" ${ARGN})
endif()
set("${outfiles}" "${${outfiles}}" PARENT_SCOPE)
endfunction()
endif()
# qt5_add_big_resources(outfiles inputfile ... )
function(qt5_add_big_resources outfiles )
@ -341,6 +384,18 @@ function(qt5_add_big_resources outfiles )
set(${outfiles} ${${outfiles}} PARENT_SCOPE)
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
function(qt_add_big_resources outfiles)
if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
qt5_add_big_resources(${outfiles} ${ARGN})
elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
qt6_add_big_resources(${outfiles} ${ARGN})
endif()
set("${outfiles}" "${${outfiles}}" PARENT_SCOPE)
endfunction()
endif()
set(_Qt5_COMPONENT_PATH "${CMAKE_CURRENT_LIST_DIR}/..")
macro(qt5_use_modules _target _link_type)
@ -413,10 +468,19 @@ function(qt5_import_plugins TARGET_NAME)
elseif(_doing STREQUAL "EXCLUDE_BY_TYPE")
string(REGEX REPLACE "[-/]" "_" _plugin_type "${_arg}")
set_property(TARGET ${TARGET_NAME} PROPERTY "QT_PLUGINS_${_plugin_type}" -)
set(_doing "")
else()
message(FATAL_ERROR "Unexpected extra argument: \"${_arg}\"")
endif()
endif()
endforeach()
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
function(qt_import_plugins)
if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
qt5_import_plugins(${ARGV})
elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
qt6_import_plugins(${ARGV})
endif()
endfunction()
endif()

View File

@ -31,3 +31,14 @@ endif()
set(Qt5DBus_QDBUSCPP2XML_EXECUTABLE Qt5::qdbuscpp2xml)
set(Qt5DBus_QDBUSXML2CPP_EXECUTABLE Qt5::qdbusxml2cpp)
# Create versionless tool targets.
foreach(__qt_tool qdbuscpp2xml qdbusxml2cpp)
if(NOT \"${QT_NO_CREATE_VERSIONLESS_TARGETS}\" AND NOT TARGET Qt::${__qt_tool}
AND TARGET Qt5::${__qt_tool})
add_executable(Qt::${__qt_tool} IMPORTED)
get_target_property(__qt_imported_location Qt5::${__qt_tool} IMPORTED_LOCATION)
set_target_properties(Qt::${__qt_tool}
PROPERTIES IMPORTED_LOCATION \"${__qt_imported_location}\")
endif()
endforeach()

View File

@ -70,6 +70,17 @@ function(qt5_add_dbus_interface _sources _interface _basename)
set(${_sources} ${${_sources}} PARENT_SCOPE)
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
function(qt_add_dbus_interface sources)
if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
qt5_add_dbus_interface("${sources}" ${ARGN})
elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
qt6_add_dbus_interface("${sources}" ${ARGN})
endif()
set("${sources}" "${${sources}}" PARENT_SCOPE)
endfunction()
endif()
function(qt5_add_dbus_interfaces _sources)
foreach(_current_FILE ${ARGN})
@ -83,6 +94,17 @@ function(qt5_add_dbus_interfaces _sources)
set(${_sources} ${${_sources}} PARENT_SCOPE)
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
function(qt_add_dbus_interfaces sources)
if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
qt5_add_dbus_interfaces("${sources}" ${ARGN})
elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
qt6_add_dbus_interfaces("${sources}" ${ARGN})
endif()
set("${sources}" "${${sources}}" PARENT_SCOPE)
endfunction()
endif()
function(qt5_generate_dbus_interface _header) # _customName OPTIONS -some -options )
set(options)
@ -116,6 +138,16 @@ function(qt5_generate_dbus_interface _header) # _customName OPTIONS -some -optio
)
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
function(qt_generate_dbus_interface)
if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
qt5_generate_dbus_interface(${ARGV})
elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
qt6_generate_dbus_interface(${ARGV})
endif()
endfunction()
endif()
function(qt5_add_dbus_adaptor _sources _xml_file _include _parentClass) # _optionalBasename _optionalClassName)
get_filename_component(_infile ${_xml_file} ABSOLUTE)
@ -152,3 +184,14 @@ function(qt5_add_dbus_adaptor _sources _xml_file _include _parentClass) # _optio
list(APPEND ${_sources} "${_impl}" "${_header}" "${_moc}")
set(${_sources} ${${_sources}} PARENT_SCOPE)
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
function(qt_add_dbus_adaptor sources)
if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
qt5_add_dbus_adaptor("${sources}" ${ARGN})
elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
qt6_add_dbus_adaptor("${sources}" ${ARGN})
endif()
set("${sources}" "${${sources}}" PARENT_SCOPE)
endfunction()
endif()

View File

@ -17,3 +17,14 @@ endif()
include(\"${CMAKE_CURRENT_LIST_DIR}/Qt5Widgets_AccessibleFactory.cmake\" OPTIONAL)
set(Qt5Widgets_UIC_EXECUTABLE Qt5::uic)
# Create versionless tool targets.
foreach(__qt_tool uic)
if(NOT \"${QT_NO_CREATE_VERSIONLESS_TARGETS}\" AND NOT TARGET Qt::${__qt_tool}
AND TARGET Qt5::${__qt_tool})
add_executable(Qt::${__qt_tool} IMPORTED)
get_target_property(__qt_imported_location Qt5::${__qt_tool} IMPORTED_LOCATION)
set_target_properties(Qt::${__qt_tool}
PROPERTIES IMPORTED_LOCATION \"${__qt_imported_location}\")
endif()
endforeach()

View File

@ -66,3 +66,15 @@ function(qt5_wrap_ui outfiles )
endforeach()
set(${outfiles} ${${outfiles}} PARENT_SCOPE)
endfunction()
# This will override the CMake upstream command, because that one is for Qt 3.
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
function(qt_wrap_ui outfiles)
if(QT_DEFAULT_MAJOR_VERSION EQUAL 5)
qt5_wrap_ui("${outfiles}" ${ARGN})
elseif(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
qt6_wrap_ui("${outfiles}" ${ARGN})
endif()
set("${outfiles}" "${${outfiles}}" PARENT_SCOPE)
endfunction()
endif()