summaryrefslogtreecommitdiffstats
path: root/src/widgets/Qt6WidgetsMacros.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/Qt6WidgetsMacros.cmake')
-rw-r--r--src/widgets/Qt6WidgetsMacros.cmake324
1 files changed, 292 insertions, 32 deletions
diff --git a/src/widgets/Qt6WidgetsMacros.cmake b/src/widgets/Qt6WidgetsMacros.cmake
index aa8133ba47..a7ff7af2f3 100644
--- a/src/widgets/Qt6WidgetsMacros.cmake
+++ b/src/widgets/Qt6WidgetsMacros.cmake
@@ -1,34 +1,6 @@
-#=============================================================================
# Copyright 2005-2011 Kitware, Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# * Neither the name of Kitware, Inc. nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#=============================================================================
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
######################################
#
@@ -36,8 +8,6 @@
#
######################################
-include(CMakeParseArguments)
-
# qt6_wrap_ui(outfiles inputfile ... )
@@ -79,3 +49,293 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
set("${outfiles}" "${${outfiles}}" PARENT_SCOPE)
endfunction()
endif()
+
+function(qt6_add_ui target)
+ if(NOT TARGET ${target})
+ message(FATAL_ERROR "Target \"${target}\" does not exist.")
+ endif()
+
+ set(options)
+ set(oneValueArgs INCLUDE_PREFIX)
+ set(multiValueArgs SOURCES OPTIONS)
+
+ cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}"
+ ${ARGN})
+
+ set(sources ${arg_SOURCES})
+ set(ui_options ${arg_OPTIONS})
+ set(raw_include_prefix "${arg_INCLUDE_PREFIX}")
+
+ if("${sources}" STREQUAL "")
+ message(FATAL_ERROR "The \"SOURCES\" parameter is empty.")
+ endif()
+
+
+ # Disable AUTOUIC for the target explicitly to avoid the AUTOUIC
+ # error message when the AUTOUIC is enabled for the target.
+ set_target_properties(${target} PROPERTIES AUTOUIC OFF)
+
+ if(NOT "${raw_include_prefix}" STREQUAL "")
+ # generate dummy `_` folders from the given path
+ # e.g. if the given path is `../a/b/c`, then the generated path will be
+ # `_`. if the given path is ``../a/../b/c`, then the generated path will
+ # be `_/_`
+ function(_qt_internal_generate_dash_path_from_input input_path
+ out_generated_dash_path)
+ string(REGEX MATCHALL "\\.\\." upper_folder_list "${input_path}")
+
+ list(JOIN upper_folder_list "" upper_folder_list)
+ string(REGEX REPLACE "\\.\\." "_/" additional_path
+ "${upper_folder_list}")
+
+ # remove last / character
+ if(NOT "${additional_path}" STREQUAL "")
+ string(LENGTH "${additional_path}" additional_path_length)
+ math(EXPR additional_path_length "${additional_path_length} - 1")
+ string(SUBSTRING "${additional_path}" 0 ${additional_path_length}
+ additional_path)
+ endif()
+
+ set(${out_generated_dash_path} "${additional_path}" PARENT_SCOPE)
+ endfunction()
+ # NOTE: If previous folders are less than ../ folder count in
+ # ${raw_include_prefix}, relative path calculation will miscalculate,
+ # so we need to add dummy folders to calculate the relative path
+ # correctly
+ _qt_internal_generate_dash_path_from_input("${raw_include_prefix}"
+ dummy_path_for_relative_calculation)
+ if(NOT "${dummy_path_for_relative_calculation}" STREQUAL "")
+ set(dummy_path_for_relative_calculation
+ "/${dummy_path_for_relative_calculation}")
+ set(raw_include_prefix_to_compare
+ "${dummy_path_for_relative_calculation}/${raw_include_prefix}")
+ else()
+ set(dummy_path_for_relative_calculation "/")
+ set(raw_include_prefix_to_compare "/${raw_include_prefix}")
+ endif()
+ # NOTE: This relative path calculation could be done just by using the
+ # below code
+ # cmake_path(RELATIVE_PATH normalized_include_prefix "${CMAKE_CURRENT_SOURCE_DIR}"
+ # but due to the backward compatibility, we need to use
+ # file(RELATIVE_PATH) and ../ folder calculation the with
+ # _qt_internal_generate_dash_path_from_input() function
+ if(WIN32)
+ set(dummy_path_for_relative_calculation
+ "${CMAKE_CURRENT_SOURCE_DIR}/${dummy_path_for_relative_calculation}")
+ set(raw_include_prefix_to_compare
+ "${CMAKE_CURRENT_SOURCE_DIR}/${raw_include_prefix_to_compare}")
+ string(REGEX REPLACE "//" "/" dummy_path_for_relative_calculation
+ "${dummy_path_for_relative_calculation}")
+ string(REGEX REPLACE "//" "/" raw_include_prefix_to_compare
+ "${raw_include_prefix_to_compare}")
+ endif()
+
+ file(RELATIVE_PATH normalized_include_prefix
+ "${dummy_path_for_relative_calculation}"
+ "${raw_include_prefix_to_compare}")
+
+ # if normalized_include_prefix ends with `/` remove it
+ string(REGEX REPLACE "/$" "" normalized_include_prefix
+ "${normalized_include_prefix}")
+
+ _qt_internal_generate_dash_path_from_input("${normalized_include_prefix}"
+ additional_path)
+ endif()
+
+ if(ui_options MATCHES "\\$<CONFIG")
+ set(is_ui_options_contains_config true)
+ endif()
+ get_property(is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+ if(is_multi AND is_ui_options_contains_config)
+ set(include_folder "$<CONFIG>")
+ endif()
+
+ set(include_folder_to_add "${include_folder}")
+ if(NOT "${additional_path}" STREQUAL "")
+ set(include_folder_to_add "${include_folder_to_add}/${additional_path}")
+ endif()
+
+ set(prefix_info_file_cmake
+ "${CMAKE_CURRENT_BINARY_DIR}/${target}_autogen/prefix_info.cmake")
+ if(EXISTS ${prefix_info_file_cmake})
+ include(${prefix_info_file_cmake})
+ set(prefix_info_file_cmake_exists true)
+ else()
+ set(prefix_info_file_cmake_exists false)
+ endif()
+
+ foreach(source_file ${sources})
+ get_filename_component(outfile "${source_file}" NAME_WE)
+ get_filename_component(infile "${source_file}" ABSOLUTE)
+ string(SHA1 infile_hash "${target}${infile}")
+ string(SUBSTRING "${infile_hash}" 0 6 short_hash)
+ set(file_ui_folder "${CMAKE_CURRENT_BINARY_DIR}/.qt/${short_hash}")
+ target_include_directories(${target} SYSTEM PRIVATE
+ "${file_ui_folder}/${include_folder_to_add}")
+
+ set(target_include_folder_with_add_path
+ "${file_ui_folder}/${include_folder}")
+ # Add additional path to include folder if it is not empty
+ if(NOT "${additional_path}" STREQUAL "")
+ set(target_include_folder_with_add_path
+ "${target_include_folder_with_add_path}/${additional_path}")
+ endif()
+
+ set(inc_dir_to_create "${target_include_folder_with_add_path}")
+ if(NOT "${raw_include_prefix}" STREQUAL "")
+ set(inc_dir_to_create
+ "${target_include_folder_with_add_path}/${raw_include_prefix}")
+ endif()
+
+ set(output_directory "${target_include_folder_with_add_path}")
+ if(NOT "${normalized_include_prefix}" STREQUAL "")
+ set(output_directory
+ "${output_directory}/${normalized_include_prefix}")
+ endif()
+
+ if(NOT EXISTS "${infile}")
+ message(FATAL_ERROR "${infile} does not exist.")
+ endif()
+ set_source_files_properties(${infile} PROPERTIES SKIP_AUTOUIC ON)
+
+ macro(_qt_internal_set_output_file_properties file)
+ set_source_files_properties(${file} PROPERTIES
+ SKIP_AUTOMOC TRUE
+ SKIP_AUTOUIC TRUE
+ SKIP_LINTING TRUE)
+ endmacro()
+
+ set(outfile "${output_directory}/ui_${outfile}.h")
+ # Before CMake 3.27, there is a bug for using $<CONFIG> in a generated
+ # file with Ninja Multi-Config generator. To avoid this issue, we need
+ # to add the generated file for each configuration.
+ # Explicitly set the output file properties for each configuration
+ # to avoid Policy CMP0071 warnings.
+ # See https://gitlab.kitware.com/cmake/cmake/-/issues/24848
+ # Xcode generator cannot handle $<CONFIG> in the output file name.
+ # it changes $<CONFIG> with NOCONFIG. That's why we need to add the
+ # generated file for each configuration for Xcode generator as well.
+ if(is_multi AND outfile MATCHES "\\$<CONFIG>"
+ AND CMAKE_VERSION VERSION_LESS "3.27"
+ OR CMAKE_GENERATOR MATCHES "Xcode")
+ foreach(config ${CMAKE_CONFIGURATION_TYPES})
+ string(REPLACE "$<CONFIG>" "${config}" outfile_with_config
+ "${outfile}")
+ _qt_internal_set_output_file_properties(
+ ${outfile_with_config})
+ target_sources(${target} PRIVATE ${outfile_with_config})
+ endforeach()
+ else()
+ _qt_internal_set_output_file_properties(${outfile})
+ target_sources(${target} PRIVATE ${outfile})
+ endif()
+ # remove double slashes
+ string(REGEX REPLACE "//" "/" outfile "${outfile}")
+
+ # Note: If INCLUDE_PREFIX is changed without changing the corresponding
+ # include path in the source file and Ninja generator is used, this
+ # casues the double build issue. To avoid this issue, we need to
+ # remove the output file in configure step if the include_prefix is
+ # changed.
+ if(CMAKE_GENERATOR MATCHES "Ninja")
+ if(prefix_info_file_cmake_exists)
+ if(NOT "${${short_hash}_prefix}" STREQUAL
+ "${normalized_include_prefix}")
+ file(REMOVE_RECURSE "${file_ui_folder}")
+ list(APPEND prefix_info_list
+ "set(${short_hash}_prefix \"${normalized_include_prefix}\")")
+ elseif(NOT DEFINED ${short_hash}_prefix)
+ list(APPEND prefix_info_list
+ "set(${short_hash}_prefix \"${normalized_include_prefix}\")")
+ endif()
+ else()
+ set(prefix_info_list "")
+ list(APPEND prefix_info_list
+ "set(${short_hash}_prefix \"${normalized_include_prefix}\")")
+ endif()
+ file(MAKE_DIRECTORY ${file_ui_folder})
+ endif()
+
+ if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.17")
+ set(remove_command rm -rf)
+ else()
+ set(remove_command "remove_directory")
+ endif()
+
+ add_custom_command(OUTPUT ${outfile}
+ DEPENDS ${QT_CMAKE_EXPORT_NAMESPACE}::uic
+ COMMAND ${CMAKE_COMMAND} -E ${remove_command} "${file_ui_folder}/${include_folder}"
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${inc_dir_to_create}
+ COMMAND ${QT_CMAKE_EXPORT_NAMESPACE}::uic ${ui_options} -o
+ ${outfile} ${infile}
+ COMMAND_EXPAND_LISTS
+ MAIN_DEPENDENCY ${infile} VERBATIM)
+ endforeach()
+
+
+ get_target_property(is_guard_on ${target} _qt_ui_property_check_guard)
+ if(NOT is_guard_on)
+ # Ninja fails when a newline is used. That's why message is
+ # divided into parts.
+ set(error_message_1
+ "Error: The target \"${target}\" has \"AUTOUIC\" enabled.")
+ set(error_message_2
+ "Error: Please disable \"AUTOUIC\" for the target \"${target}\".")
+
+ set(ui_property_check_dummy_file
+ "${CMAKE_CURRENT_BINARY_DIR}/${target}_autogen/ui_property_check_timestamp")
+
+ add_custom_command(OUTPUT ${ui_property_check_dummy_file}
+ COMMAND ${CMAKE_COMMAND} -E make_directory
+ "${CMAKE_CURRENT_BINARY_DIR}/${target}_autogen"
+ COMMAND ${CMAKE_COMMAND} -E touch ${ui_property_check_dummy_file}
+ COMMAND
+ "$<$<BOOL:$<TARGET_PROPERTY:${target},AUTOUIC>>:${CMAKE_COMMAND}\
+;-E;echo;${error_message_1}>"
+ COMMAND
+ "$<$<BOOL:$<TARGET_PROPERTY:${target},AUTOUIC>>:${CMAKE_COMMAND}\
+;-E;echo;${error_message_2}>"
+ # Remove the dummy file so that the error message is shown until
+ # the AUTOUIC is disabled. Otherwise, the error message is shown
+ # only once when the AUTOUIC is enabled with Visual Studio generator.
+ COMMAND
+ "$<$<BOOL:$<TARGET_PROPERTY:${target},AUTOUIC>>:${CMAKE_COMMAND}\
+;-E;remove;${ui_property_check_dummy_file}>"
+ COMMAND
+ "$<$<BOOL:$<TARGET_PROPERTY:${target},AUTOUIC>>:${CMAKE_COMMAND}\
+;-E;false>"
+ COMMAND_EXPAND_LISTS
+ VERBATIM)
+
+ # When AUTOUIC is enabled, AUTOUIC runs before ${target}_ui_property_check
+ # target. So we need to add ${target}_ui_property_check as a dependency
+ # to ${target} to make sure that AUTOUIC runs after ${target}_ui_property_check
+ if (NOT QT_NO_MIX_UI_AUTOUIC_CHECK)
+ set_target_properties(${target} PROPERTIES
+ _qt_ui_property_check_guard ON)
+ add_custom_target(${target}_ui_property_check
+ ALL DEPENDS ${ui_property_check_dummy_file})
+ _qt_internal_assign_to_internal_targets_folder(
+ ${target}_ui_property_check)
+ add_dependencies(${target} ${target}_ui_property_check)
+ endif()
+ endif()
+
+ # write prefix info file
+ if(CMAKE_GENERATOR MATCHES "Ninja")
+ list(PREPEND prefix_info_list "include_guard()")
+ string(REPLACE ";" "\n" prefix_info_list "${prefix_info_list}")
+ file(WRITE "${prefix_info_file_cmake}" "${prefix_info_list}")
+ endif()
+endfunction()
+
+if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
+ function(qt_add_ui)
+ if(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
+ qt6_add_ui(${ARGN})
+ else()
+ message(FATAL_ERROR "qt_add_ui() is only available in Qt 6.")
+ endif()
+ endfunction()
+endif()
+