summaryrefslogtreecommitdiffstats
path: root/cmake/QtAutogenHelpers.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/QtAutogenHelpers.cmake')
-rw-r--r--cmake/QtAutogenHelpers.cmake216
1 files changed, 216 insertions, 0 deletions
diff --git a/cmake/QtAutogenHelpers.cmake b/cmake/QtAutogenHelpers.cmake
new file mode 100644
index 0000000000..029a709e90
--- /dev/null
+++ b/cmake/QtAutogenHelpers.cmake
@@ -0,0 +1,216 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Initial autogen setup for a target to specify certain CMake properties which are common
+# to all autogen tools. Also enable AUTOMOC by default.
+function(qt_autogen_tools_initial_setup target)
+ set_property(TARGET "${target}" PROPERTY INTERFACE_QT_MAJOR_VERSION ${PROJECT_VERSION_MAJOR})
+ set_property(TARGET "${target}" APPEND PROPERTY COMPATIBLE_INTERFACE_STRING QT_MAJOR_VERSION)
+
+ set_directory_properties(PROPERTIES
+ QT_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}
+ QT_VERSION_MINOR ${PROJECT_VERSION_MINOR}
+ QT_VERSION_PATCH ${PROJECT_VERSION_PATCH}
+ )
+
+ qt_enable_autogen_tool(${target} "moc" ON)
+endfunction()
+
+# Enables or disables an autogen tool like moc, uic or rcc on ${target}.
+function(qt_enable_autogen_tool target tool enable)
+ string(TOUPPER "${tool}" captitalAutogenTool)
+
+ get_target_property(tool_enabled ${target} AUTO${captitalAutogenTool})
+ get_target_property(autogen_target_depends ${target} AUTOGEN_TARGET_DEPENDS)
+
+ if(NOT autogen_target_depends)
+ set(autogen_target_depends "")
+ endif()
+ set(tool_executable "$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::${tool}>")
+ set(tool_target_name ${QT_CMAKE_EXPORT_NAMESPACE}::${tool})
+
+ if(enable)
+ list(APPEND autogen_target_depends ${tool_target_name})
+ else()
+ list(REMOVE_ITEM autogen_target_depends ${tool_target_name})
+ endif()
+
+ # f66c1db16c050c9d685a44a38ad7c5cf9f6fcc96 in qtbase introduced a new macro
+ # that the moc scanner has to look for. Inform the CMake moc scanner about it.
+ if(tool STREQUAL "moc" AND enable)
+ set_target_properties("${target}" PROPERTIES
+ AUTOMOC_MACRO_NAMES "${CMAKE_AUTOMOC_MACRO_NAMES};Q_ENUM_NS;Q_GADGET_EXPORT")
+ if (TARGET Qt::Platform)
+ get_target_property(_abi_tag Qt::Platform qt_libcpp_abi_tag)
+ if (_abi_tag)
+ set_property(TARGET "${target}" APPEND PROPERTY
+ AUTOMOC_MOC_OPTIONS --libcpp-abi-version "${_abi_tag}"
+ )
+ endif()
+ endif()
+ endif()
+
+ set_target_properties("${target}"
+ PROPERTIES
+ AUTO${captitalAutogenTool} "${enable}"
+ AUTO${captitalAutogenTool}_EXECUTABLE "${tool_executable}"
+ AUTOGEN_TARGET_DEPENDS "${autogen_target_depends}"
+ )
+endfunction()
+
+# This function adds or removes additional AUTOGEN tools to a target: AUTOMOC/UIC/RCC
+function(qt_autogen_tools target)
+ cmake_parse_arguments(PARSE_ARGV 1 arg "" "" "${__default_private_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(arg_ENABLE_AUTOGEN_TOOLS)
+ foreach(tool ${arg_ENABLE_AUTOGEN_TOOLS})
+ qt_enable_autogen_tool(${target} ${tool} ON)
+ endforeach()
+ endif()
+
+ if(arg_DISABLE_AUTOGEN_TOOLS)
+ foreach(tool ${arg_DISABLE_AUTOGEN_TOOLS})
+ qt_enable_autogen_tool(${target} ${tool} OFF)
+ endforeach()
+ endif()
+endfunction()
+
+# Complete manual moc invocation with full control.
+# Use AUTOMOC whenever possible.
+# Multi-value Arguments:
+# INCLUDE_DIRECTORIES
+# Specifies a list of include directories used by 'moc'.
+# INCLUDE_DIRECTORY_TARGETS
+# Specifies a list of targets to extract the INTERFACE_INCLUDE_DIRECTORIES
+# property and use it as the 'moc' include directories.(Deprecated use TARGETS instead)
+# DEFINITIONS
+# List of the definitions that should be added to the moc command line arguments.
+# Supports the syntax both with and without the prepending '-D'.
+# TARGETS
+# The list of targets that will be used to collect the INTERFACE_INCLUDE_DIRECTORIES,
+# INCLUDE_DIRECTORIES, and COMPILE_DEFINITIONS properties.
+function(qt_manual_moc result)
+ cmake_parse_arguments(arg
+ ""
+ "OUTPUT_MOC_JSON_FILES"
+ "FLAGS;INCLUDE_DIRECTORIES;INCLUDE_DIRECTORY_TARGETS;DEFINITIONS;TARGETS"
+ ${ARGN})
+ set(moc_files)
+ set(metatypes_json_list)
+ foreach(infile ${arg_UNPARSED_ARGUMENTS})
+ qt_make_output_file("${infile}" "moc_" ".cpp"
+ "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" outfile)
+ list(APPEND moc_files "${outfile}")
+
+ set(moc_parameters_file "${outfile}_parameters$<$<BOOL:$<CONFIG>>:_$<CONFIG>>")
+ set(moc_parameters ${arg_FLAGS} -o "${outfile}" "${infile}")
+
+ foreach(dir IN ITEMS ${arg_INCLUDE_DIRECTORIES})
+ list(APPEND moc_parameters
+ "-I\n${dir}")
+ endforeach()
+
+ foreach(dep IN LISTS arg_INCLUDE_DIRECTORY_TARGETS arg_TARGETS)
+ set(include_expr "$<TARGET_PROPERTY:${dep},INTERFACE_INCLUDE_DIRECTORIES>")
+ list(APPEND moc_parameters
+ "$<$<BOOL:${include_expr}>:-I\n$<JOIN:${include_expr},\n-I\n>>")
+
+ if(APPLE AND TARGET ${dep})
+ get_target_property(is_versionless ${dep} _qt_is_versionless_target)
+ if(is_versionless)
+ string(REGEX REPLACE "^Qt::(.*)" "\\1" dep "${dep}")
+ set(dep "${QT_CMAKE_EXPORT_NAMESPACE}::${dep}")
+ endif()
+
+ get_target_property(alias_dep ${dep} ALIASED_TARGET)
+ if(alias_dep)
+ set(dep ${alias_dep})
+ endif()
+
+ get_target_property(loc ${dep} IMPORTED_LOCATION)
+ string(REGEX REPLACE "(.*)/Qt[^/]+\\.framework.*" "\\1" loc "${loc}")
+
+ if(loc)
+ list(APPEND moc_parameters "\n-F\n${loc}\n")
+ endif()
+ endif()
+ endforeach()
+
+ foreach(dep IN LISTS arg_TARGETS)
+ set(include_property_expr
+ "$<TARGET_GENEX_EVAL:${dep},$<TARGET_PROPERTY:${dep},INCLUDE_DIRECTORIES>>")
+ list(APPEND moc_parameters
+ "$<$<BOOL:${include_property_expr}>:-I\n$<JOIN:${include_property_expr},\n-I\n>>")
+
+ set(defines_property_expr
+ "$<TARGET_GENEX_EVAL:${dep},$<TARGET_PROPERTY:${dep},COMPILE_DEFINITIONS>>")
+ set(defines_with_d "$<FILTER:${defines_property_expr},INCLUDE,^-D>")
+ set(defines_without_d "$<FILTER:${defines_property_expr},EXCLUDE,^-D>")
+ list(APPEND moc_parameters
+ "$<$<BOOL:${defines_with_d}>:$<JOIN:${defines_with_d},\n>>")
+ list(APPEND moc_parameters
+ "$<$<BOOL:${defines_without_d}>:-D\n$<JOIN:${defines_without_d},\n-D\n>>")
+ endforeach()
+
+ foreach(def IN LISTS arg_DEFINITIONS)
+ if(NOT def MATCHES "^-D")
+ list(APPEND moc_parameters "-D\n${def}")
+ else()
+ list(APPEND moc_parameters "${def}")
+ endif()
+ endforeach()
+
+ set(metatypes_byproducts)
+ if (arg_OUTPUT_MOC_JSON_FILES)
+ set(moc_json_file "${outfile}.json")
+ list(APPEND moc_parameters --output-json)
+ list(APPEND metatypes_json_list "${outfile}.json")
+ set(metatypes_byproducts "${outfile}.json")
+ endif()
+
+ if (TARGET Qt::Platform)
+ get_target_property(_abi_tag Qt::Platform qt_libcpp_abi_tag)
+ if (_abi_tag)
+ list(APPEND moc_parameters --libcpp-abi-version "${_abi_tag}")
+ endif()
+ endif()
+
+ string (REPLACE ";" "\n" moc_parameters "${moc_parameters}")
+
+ file(GENERATE OUTPUT "${moc_parameters_file}" CONTENT "${moc_parameters}\n")
+
+ add_custom_command(OUTPUT "${outfile}" ${metatypes_byproducts}
+ COMMAND ${QT_CMAKE_EXPORT_NAMESPACE}::moc "@${moc_parameters_file}"
+ DEPENDS "${infile}" ${moc_depends} ${QT_CMAKE_EXPORT_NAMESPACE}::moc
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" VERBATIM)
+ endforeach()
+ set("${result}" ${moc_files} PARENT_SCOPE)
+
+ # Register generated json files
+ if (arg_OUTPUT_MOC_JSON_FILES)
+ set(${arg_OUTPUT_MOC_JSON_FILES} "${metatypes_json_list}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# From Qt6CoreMacros
+# Function used to create the names of output files preserving relative dirs
+function(qt_make_output_file infile prefix suffix source_dir binary_dir result)
+ get_filename_component(outfilename "${infile}" NAME_WE)
+
+ set(base_dir "${source_dir}")
+ string(FIND "${infile}" "${binary_dir}/" in_binary)
+ if (in_binary EQUAL 0)
+ set(base_dir "${binary_dir}")
+ endif()
+
+ get_filename_component(abs_infile "${infile}" ABSOLUTE BASE_DIR "${base_dir}")
+ file(RELATIVE_PATH rel_infile "${base_dir}" "${abs_infile}")
+ string(REPLACE "../" "__/" mapped_infile "${rel_infile}")
+
+ get_filename_component(abs_mapped_infile "${mapped_infile}" ABSOLUTE BASE_DIR "${binary_dir}")
+ get_filename_component(outpath "${abs_mapped_infile}" PATH)
+
+ file(MAKE_DIRECTORY "${outpath}")
+ set("${result}" "${outpath}/${prefix}${outfilename}${suffix}" PARENT_SCOPE)
+endfunction()