Add support for Qt header_modules aka a header only INTERFACE library
Also add support for modules that have no private module counterpart. Both are needed for Designer's QtUiPlugin in qttools. Change-Id: Ia7e9d8837140e1de5cd59e196b4f63481ab68298 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io> Reviewed-by: Qt CMake Build Bot
This commit is contained in:
parent
02074bf345
commit
54aeb4ccd7
@ -383,7 +383,7 @@ endfunction()
|
||||
|
||||
# Generates module .pri files for consumption by qmake
|
||||
function(qt_generate_module_pri_file target target_path pri_files_var)
|
||||
set(flags INTERNAL_MODULE)
|
||||
set(flags INTERNAL_MODULE HEADER_MODULE)
|
||||
set(options)
|
||||
set(multiopts QMAKE_MODULE_CONFIG)
|
||||
cmake_parse_arguments(arg "${flags}" "${options}" "${multiopts}" ${ARGN})
|
||||
@ -391,10 +391,19 @@ function(qt_generate_module_pri_file target target_path pri_files_var)
|
||||
qt_internal_module_info(module "${target}")
|
||||
set(pri_files)
|
||||
|
||||
get_target_property(enabled_features "${target}" QT_ENABLED_PUBLIC_FEATURES)
|
||||
get_target_property(disabled_features "${target}" QT_DISABLED_PUBLIC_FEATURES)
|
||||
get_target_property(enabled_private_features "${target}" QT_ENABLED_PRIVATE_FEATURES)
|
||||
get_target_property(disabled_private_features "${target}" QT_DISABLED_PRIVATE_FEATURES)
|
||||
set(property_prefix)
|
||||
if(arg_HEADER_MODULE)
|
||||
set(property_prefix "interface_")
|
||||
endif()
|
||||
|
||||
get_target_property(enabled_features "${target}"
|
||||
"${property_prefix}QT_ENABLED_PUBLIC_FEATURES")
|
||||
get_target_property(disabled_features "${target}"
|
||||
"${property_prefix}QT_DISABLED_PUBLIC_FEATURES")
|
||||
get_target_property(enabled_private_features "${target}"
|
||||
"${property_prefix}QT_ENABLED_PRIVATE_FEATURES")
|
||||
get_target_property(disabled_private_features "${target}"
|
||||
"${property_prefix}QT_DISABLED_PRIVATE_FEATURES")
|
||||
|
||||
foreach(var enabled_features disabled_features enabled_private_features disabled_private_features)
|
||||
if(${var} STREQUAL "${var}-NOTFOUND")
|
||||
@ -901,7 +910,7 @@ function(extend_target target)
|
||||
if (NOT TARGET "${target}")
|
||||
message(FATAL_ERROR "Trying to extend non-existing target \"${target}\".")
|
||||
endif()
|
||||
qt_parse_all_arguments(arg "extend_target" "" ""
|
||||
qt_parse_all_arguments(arg "extend_target" "HEADER_MODULE" ""
|
||||
"CONDITION;${__default_public_args};${__default_private_args};COMPILE_FLAGS" ${ARGN})
|
||||
if ("x${arg_CONDITION}" STREQUAL x)
|
||||
set(arg_CONDITION ON)
|
||||
@ -949,16 +958,35 @@ function(extend_target target)
|
||||
if (arg_COMPILE_FLAGS)
|
||||
set_source_files_properties(${arg_SOURCES} PROPERTIES COMPILE_FLAGS "${arg_COMPILE_FLAGS}")
|
||||
endif()
|
||||
target_include_directories("${target}" PUBLIC ${arg_PUBLIC_INCLUDE_DIRECTORIES} PRIVATE ${arg_INCLUDE_DIRECTORIES})
|
||||
target_compile_definitions("${target}" PUBLIC ${arg_PUBLIC_DEFINES} PRIVATE ${arg_DEFINES})
|
||||
target_link_libraries("${target}" PUBLIC ${arg_PUBLIC_LIBRARIES} PRIVATE ${arg_LIBRARIES})
|
||||
target_compile_options("${target}" PUBLIC ${arg_PUBLIC_COMPILE_OPTIONS} PRIVATE ${arg_COMPILE_OPTIONS})
|
||||
target_link_options("${target}" PUBLIC ${arg_PUBLIC_LINK_OPTIONS} PRIVATE ${arg_LINK_OPTIONS})
|
||||
|
||||
set_target_properties("${target}" PROPERTIES
|
||||
AUTOMOC_MOC_OPTIONS "${arg_MOC_OPTIONS}"
|
||||
_qt_target_deps "${target_deps}"
|
||||
)
|
||||
set(public_visibility_option "PUBLIC")
|
||||
set(private_visibility_option "PRIVATE")
|
||||
if(arg_HEADER_MODULE)
|
||||
set(public_visibility_option "INTERFACE")
|
||||
set(private_visibility_option "INTERFACE")
|
||||
endif()
|
||||
target_include_directories("${target}"
|
||||
${public_visibility_option} ${arg_PUBLIC_INCLUDE_DIRECTORIES}
|
||||
${private_visibility_option} ${arg_INCLUDE_DIRECTORIES})
|
||||
target_compile_definitions("${target}"
|
||||
${public_visibility_option} ${arg_PUBLIC_DEFINES}
|
||||
${private_visibility_option} ${arg_DEFINES})
|
||||
target_link_libraries("${target}"
|
||||
${public_visibility_option} ${arg_PUBLIC_LIBRARIES}
|
||||
${private_visibility_option} ${arg_LIBRARIES})
|
||||
target_compile_options("${target}"
|
||||
${public_visibility_option} ${arg_PUBLIC_COMPILE_OPTIONS}
|
||||
${private_visibility_option} ${arg_COMPILE_OPTIONS})
|
||||
target_link_options("${target}"
|
||||
${public_visibility_option} ${arg_PUBLIC_LINK_OPTIONS}
|
||||
${private_visibility_option} ${arg_LINK_OPTIONS})
|
||||
|
||||
if(NOT arg_HEADER_MODULE)
|
||||
set_target_properties("${target}" PROPERTIES
|
||||
AUTOMOC_MOC_OPTIONS "${arg_MOC_OPTIONS}"
|
||||
_qt_target_deps "${target_deps}"
|
||||
)
|
||||
endif()
|
||||
|
||||
# When computing the private library dependencies, we need to check not only the known
|
||||
# modules added by this repo's qt_build_repo(), but also all module dependencies that
|
||||
@ -1172,7 +1200,7 @@ function(add_qt_module target)
|
||||
|
||||
# Process arguments:
|
||||
qt_parse_all_arguments(arg "add_qt_module"
|
||||
"NO_MODULE_HEADERS;STATIC;DISABLE_TOOLS_EXPORT;EXCEPTIONS;INTERNAL_MODULE;NO_SYNC_QT"
|
||||
"NO_MODULE_HEADERS;STATIC;DISABLE_TOOLS_EXPORT;EXCEPTIONS;INTERNAL_MODULE;NO_SYNC_QT;NO_PRIVATE_MODULE;HEADER_MODULE"
|
||||
"CONFIG_MODULE_NAME"
|
||||
"${__default_private_args};${__default_public_args};QMAKE_MODULE_CONFIG;EXTRA_CMAKE_FILES;EXTRA_CMAKE_INCLUDES" ${ARGN})
|
||||
|
||||
@ -1183,7 +1211,9 @@ function(add_qt_module target)
|
||||
qt_internal_add_qt_repo_known_module("${target}")
|
||||
|
||||
### Define Targets:
|
||||
if(${arg_STATIC})
|
||||
if(${arg_HEADER_MODULE})
|
||||
add_library("${target}" INTERFACE)
|
||||
elseif(${arg_STATIC})
|
||||
add_library("${target}" STATIC)
|
||||
elseif(${QT_BUILD_SHARED_LIBS})
|
||||
add_library("${target}" SHARED)
|
||||
@ -1193,13 +1223,15 @@ function(add_qt_module target)
|
||||
qt_internal_add_target_aliases("${target}")
|
||||
|
||||
# Add _private target to link against the private headers:
|
||||
set(target_private "${target}Private")
|
||||
add_library("${target_private}" INTERFACE)
|
||||
qt_internal_add_target_aliases("${target_private}")
|
||||
if(NOT ${arg_NO_PRIVATE_MODULE})
|
||||
set(target_private "${target}Private")
|
||||
add_library("${target_private}" INTERFACE)
|
||||
qt_internal_add_target_aliases("${target_private}")
|
||||
endif()
|
||||
|
||||
# Module headers:
|
||||
if(${arg_NO_MODULE_HEADERS} OR ${arg_NO_SYNC_QT})
|
||||
set_target_properties("${target}" PROPERTIES MODULE_HAS_HEADERS OFF)
|
||||
set_target_properties("${target}" PROPERTIES INTERFACE_MODULE_HAS_HEADERS OFF)
|
||||
else()
|
||||
# Use QT_BUILD_DIR for the syncqt call.
|
||||
# So we either write the generated files into the qtbase non-prefix build root, or the
|
||||
@ -1215,7 +1247,7 @@ function(add_qt_module target)
|
||||
"${PROJECT_SOURCE_DIR}")
|
||||
execute_process(COMMAND ${syncqt_full_command})
|
||||
|
||||
set_target_properties("${target}" PROPERTIES MODULE_HAS_HEADERS ON)
|
||||
set_target_properties("${target}" PROPERTIES INTERFACE_MODULE_HAS_HEADERS ON)
|
||||
|
||||
### FIXME: Can we replace headers.pri?
|
||||
qt_read_headers_pri("${target}" "module_headers")
|
||||
@ -1227,25 +1259,29 @@ function(add_qt_module target)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Plugin types associated to a module
|
||||
if(NOT "x${arg_PLUGIN_TYPES}" STREQUAL "x")
|
||||
set_target_properties("${target}" PROPERTIES MODULE_PLUGIN_TYPES "${arg_PLUGIN_TYPES}")
|
||||
endif()
|
||||
if(NOT arg_HEADER_MODULE)
|
||||
# Plugin types associated to a module
|
||||
if(NOT "x${arg_PLUGIN_TYPES}" STREQUAL "x")
|
||||
set_target_properties("${target}" PROPERTIES MODULE_PLUGIN_TYPES "${arg_PLUGIN_TYPES}")
|
||||
endif()
|
||||
|
||||
set_target_properties("${target}" PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
OUTPUT_NAME "${INSTALL_CMAKE_NAMESPACE}${target}"
|
||||
)
|
||||
set_target_properties("${target}" PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
OUTPUT_NAME "${INSTALL_CMAKE_NAMESPACE}${target}"
|
||||
)
|
||||
endif()
|
||||
|
||||
qt_internal_library_deprecation_level(deprecation_define)
|
||||
|
||||
qt_autogen_tools_initial_setup(${target})
|
||||
if(NOT arg_HEADER_MODULE)
|
||||
qt_autogen_tools_initial_setup(${target})
|
||||
endif()
|
||||
|
||||
set(private_includes
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
@ -1267,7 +1303,13 @@ function(add_qt_module target)
|
||||
endif()
|
||||
list(APPEND public_includes ${arg_PUBLIC_INCLUDE_DIRECTORIES})
|
||||
|
||||
set(header_module)
|
||||
if(arg_HEADER_MODULE)
|
||||
set(header_module "HEADER_MODULE")
|
||||
endif()
|
||||
|
||||
extend_target("${target}"
|
||||
${header_module}
|
||||
SOURCES ${arg_SOURCES}
|
||||
INCLUDE_DIRECTORIES
|
||||
${private_includes}
|
||||
@ -1301,7 +1343,7 @@ function(add_qt_module target)
|
||||
DISABLE_AUTOGEN_TOOLS ${arg_DISABLE_AUTOGEN_TOOLS}
|
||||
)
|
||||
|
||||
if(NOT ${arg_EXCEPTIONS})
|
||||
if(NOT ${arg_EXCEPTIONS} AND NOT ${arg_HEADER_MODULE})
|
||||
qt_internal_set_no_exceptions_flags("${target}")
|
||||
endif()
|
||||
|
||||
@ -1399,7 +1441,10 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})")
|
||||
)
|
||||
|
||||
file(COPY ${extra_cmake_files} DESTINATION "${config_build_dir}")
|
||||
set(exported_targets ${target} ${target_private})
|
||||
set(exported_targets ${target})
|
||||
if(NOT ${arg_NO_PRIVATE_MODULE})
|
||||
list(APPEND exported_targets ${target_private})
|
||||
endif()
|
||||
set(export_name "${INSTALL_CMAKE_NAMESPACE}${target}Targets")
|
||||
qt_install(TARGETS ${exported_targets}
|
||||
EXPORT ${export_name}
|
||||
@ -1435,6 +1480,7 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})")
|
||||
qt_path_join(pri_target_path ${PROJECT_BINARY_DIR} mkspecs/modules)
|
||||
qt_generate_module_pri_file("${target}" "${pri_target_path}" module_pri_files
|
||||
${arg_INTERNAL_MODULE}
|
||||
${header_module}
|
||||
QMAKE_MODULE_CONFIG
|
||||
${arg_QMAKE_MODULE_CONFIG}
|
||||
)
|
||||
@ -1442,7 +1488,9 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})")
|
||||
|
||||
### fixme: cmake is missing a built-in variable for this. We want to apply it only to modules and plugins
|
||||
# that belong to Qt.
|
||||
qt_internal_add_link_flags_no_undefined("${target}")
|
||||
if(NOT arg_HEADER_MODULE)
|
||||
qt_internal_add_link_flags_no_undefined("${target}")
|
||||
endif()
|
||||
|
||||
set(interface_includes
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>"
|
||||
@ -1457,9 +1505,10 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})")
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories("${target_private}" INTERFACE
|
||||
${interface_includes}
|
||||
)
|
||||
|
||||
if(NOT ${arg_NO_PRIVATE_MODULE})
|
||||
target_include_directories("${target_private}" INTERFACE ${interface_includes})
|
||||
endif()
|
||||
|
||||
if(NOT ${arg_DISABLE_TOOLS_EXPORT})
|
||||
qt_export_tools(${target})
|
||||
|
@ -54,7 +54,16 @@ macro(qt_collect_third_party_deps)
|
||||
endmacro()
|
||||
|
||||
function(qt_internal_create_module_depends_file target)
|
||||
get_target_property(depends "${target}" LINK_LIBRARIES)
|
||||
get_target_property(target_type "${target}" TYPE)
|
||||
if(target_type STREQUAL "INTERFACE_LIBRARY")
|
||||
set(arg_HEADER_MODULE ON)
|
||||
else()
|
||||
set(arg_HEADER_MODULE OFF)
|
||||
endif()
|
||||
|
||||
if(NOT arg_HEADER_MODULE)
|
||||
get_target_property(depends "${target}" LINK_LIBRARIES)
|
||||
endif()
|
||||
get_target_property(public_depends "${target}" INTERFACE_LINK_LIBRARIES)
|
||||
|
||||
# Used for collecting Qt module dependencies that should be find_package()'d in
|
||||
@ -62,7 +71,9 @@ function(qt_internal_create_module_depends_file target)
|
||||
get_target_property(target_deps "${target}" _qt_target_deps)
|
||||
set(target_deps_seen "")
|
||||
|
||||
get_target_property(extra_depends "${target}" QT_EXTRA_PACKAGE_DEPENDENCIES)
|
||||
if(NOT arg_HEADER_MODULE)
|
||||
get_target_property(extra_depends "${target}" QT_EXTRA_PACKAGE_DEPENDENCIES)
|
||||
endif()
|
||||
if(NOT extra_depends STREQUAL "${extra_depends}-NOTFOUND")
|
||||
list(APPEND target_deps ${extra_depends})
|
||||
endif()
|
||||
@ -140,7 +151,7 @@ function(qt_internal_create_module_depends_file target)
|
||||
list(REMOVE_DUPLICATES qtdeps)
|
||||
endif()
|
||||
|
||||
get_target_property(hasModuleHeaders "${target}" MODULE_HAS_HEADERS)
|
||||
get_target_property(hasModuleHeaders "${target}" INTERFACE_MODULE_HAS_HEADERS)
|
||||
if (${hasModuleHeaders})
|
||||
qt_internal_write_depends_file("${target}" ${qtdeps})
|
||||
endif()
|
||||
@ -260,6 +271,11 @@ function(qt_internal_create_plugins_files)
|
||||
|
||||
message("Generating Plugins files for ${repo_known_modules}...")
|
||||
foreach (QT_MODULE ${repo_known_modules})
|
||||
get_target_property(target_type "${QT_MODULE}" TYPE)
|
||||
if(target_type STREQUAL "INTERFACE_LIBRARY")
|
||||
# No plugins are provided by a header only module.
|
||||
continue()
|
||||
endif()
|
||||
qt_path_join(config_build_dir ${QT_CONFIG_BUILD_DIR} ${INSTALL_CMAKE_NAMESPACE}${QT_MODULE})
|
||||
qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${INSTALL_CMAKE_NAMESPACE}${QT_MODULE})
|
||||
set(QT_MODULE_PLUGIN_INCLUDES "")
|
||||
|
@ -1962,6 +1962,10 @@ def write_module(cm_fh: typing.IO[str], scope: Scope, *,
|
||||
extra.append('NO_MODULE_HEADERS')
|
||||
if 'minimal_syncqt' in scope.get('CONFIG'):
|
||||
extra.append('NO_SYNC_QT')
|
||||
if 'no_private_module' in scope.get('CONFIG'):
|
||||
extra.append('NO_PRIVATE_MODULE')
|
||||
if 'header_module' in scope.get('CONFIG'):
|
||||
extra.append('HEADER_MODULE')
|
||||
|
||||
module_config = scope.get("MODULE_CONFIG")
|
||||
if len(module_config):
|
||||
|
Loading…
Reference in New Issue
Block a user