123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- #
- # Copyright (c) Contributors to the Open 3D Engine Project.
- # For complete copyright and license terms please see the LICENSE at the root of this distribution.
- #
- # SPDX-License-Identifier: Apache-2.0 OR MIT
- #
- #
- if(TARGET 3rdParty::Qt::Core) # Check we are not called multiple times
- return()
- endif()
- set(QT_PACKAGE_NAME qt)
- set(QT_PATH "${CMAKE_CURRENT_LIST_DIR}/qt-wayland" CACHE STRING "The root path to Qt" FORCE)
- mark_as_advanced(QT_PATH)
- if(NOT EXISTS ${QT_PATH})
- message(FATAL_ERROR "Cannot find 3rdParty library ${QT_PACKAGE_NAME} on path ${QT_PATH}")
- endif()
- # Force-set QtCore's version here to ensure CMake detects Qt's existence and allows AUTOMOC to work
- set(Qt5Core_VERSION_MAJOR "5" CACHE STRING "Qt's major version" FORCE)
- set(Qt5Core_VERSION_MINOR "15" CACHE STRING "Qt's minor version" FORCE)
- set(Qt5Core_VERSION_PATCH "2" CACHE STRING "Qt's patch version" FORCE)
- mark_as_advanced(Qt5Core_VERSION_MAJOR)
- mark_as_advanced(Qt5Core_VERSION_MINOR)
- mark_as_advanced(Qt5Core_VERSION_PATCH)
- set(QT5_COMPONENTS
- Core
- Concurrent
- Gui
- LinguistTools
- Network
- OpenGL
- Svg
- Test
- Widgets
- Xml
- )
- include(${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}/Qt_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
- list(APPEND CMAKE_PREFIX_PATH ${QT_LIB_PATH}/cmake/Qt5)
- # Clear the cache for found DIRs
- unset(Qt5_DIR CACHE)
- foreach(component ${QT5_COMPONENTS})
- unset(Qt5${component}_DIR CACHE)
- endforeach()
- unset(Qt5Positioning_DIR CACHE)
- unset(Qt5PrintSupport_DIR CACHE)
- unset(Qt5Qml_DIR CACHE)
- unset(Qt5QmlModels_DIR CACHE)
- unset(Qt5Quick_DIR CACHE)
- # Populate the Qt5 configurations
- find_package(Qt5
- COMPONENTS ${QT5_COMPONENTS}
- REQUIRED
- NO_CMAKE_PACKAGE_REGISTRY
- )
- # Now create libraries that wrap the dependency so we can refer to them in our format
- foreach(component ${QT5_COMPONENTS})
- if(TARGET Qt5::${component})
- # Convert the includes to system includes
- get_target_property(system_includes Qt5::${component} INTERFACE_INCLUDE_DIRECTORIES)
- set_target_properties(Qt5::${component} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "") # Clear it in case someone refers to it
- ly_target_include_system_directories(TARGET Qt5::${component}
- INTERFACE ${system_includes}
- )
- # Alias the target with our prefix
- add_library(3rdParty::Qt::${component} ALIAS Qt5::${component})
- mark_as_advanced(Qt5${component}_DIR) # Hiding from GUI
- # Qt only has debug and release, we map the configurations we use in o3de. We map all the configurations
- # except debug to release
- foreach(conf IN LISTS CMAKE_CONFIGURATION_TYPES)
- string(TOUPPER ${conf} UCONF)
- ly_qt_configuration_mapping(${UCONF} MAPPED_CONF)
- set_target_properties(Qt5::${component} PROPERTIES
- MAP_IMPORTED_CONFIG_${UCONF} ${MAPPED_CONF}
- )
- endforeach()
- endif()
- endforeach()
- # Some extra DIR variables we want to hide from GUI
- mark_as_advanced(Qt5_DIR) # Hiding from GUI
- mark_as_advanced(Qt5LinguistTools_DIR) # Hiding from GUI, this variable comes from the LinguistTools module
- mark_as_advanced(Qt5Positioning_DIR)
- mark_as_advanced(Qt5PrintSupport_DIR)
- mark_as_advanced(Qt5Qml_DIR)
- mark_as_advanced(Qt5QmlModels_DIR)
- mark_as_advanced(Qt5Quick_DIR)
- # Special case for Qt::Gui, we are using the private headers...
- ly_target_include_system_directories(TARGET Qt5::Gui
- INTERFACE "${Qt5Gui_PRIVATE_INCLUDE_DIRS}"
- )
- # Another special case: Qt:Widgets, we are also using private headers
- ly_target_include_system_directories(TARGET Qt5::Widgets
- INTERFACE "${Qt5Widgets_PRIVATE_INCLUDE_DIRS}"
- )
- # Qt plugins/translations/aux files.
- # We create libraries that wraps them so they get deployed properly.
- # This used to be deployed through winqtdeploy/macqtdeploy, however, those tools
- # are old and unmaintaned, macqtdeploy takes long times to run
- add_library(3rdParty::Qt::Core::Translations INTERFACE IMPORTED GLOBAL)
- file(GLOB tranlation_files ${QT_PATH}/translations/qt_*.qm)
- if(tranlation_files)
- ly_add_target_files(TARGETS 3rdParty::Qt::Core::Translations
- FILES ${tranlation_files}
- OUTPUT_SUBDIRECTORY translations
- )
- endif()
- ly_add_dependencies(Qt5::Core 3rdParty::Qt::Core::Translations)
- # plugins, each platform will define the files it has and the OUTPUT_SUBDIRECTORY
- set(QT_PLUGINS
- Network
- Gui
- Widgets
- )
- foreach(plugin ${QT_PLUGINS})
- add_library(3rdParty::Qt::${plugin}::Plugins INTERFACE IMPORTED GLOBAL)
- ly_add_dependencies(Qt5::${plugin} 3rdParty::Qt::${plugin}::Plugins)
- endforeach()
- include(${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}/QtPlugin_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
- # UIC executable
- unset(QT_UIC_EXECUTABLE CACHE)
- find_program(QT_UIC_EXECUTABLE uic HINTS "${QT_PATH}/bin")
- mark_as_advanced(QT_UIC_EXECUTABLE) # Hiding from GUI
- # RCC executable
- unset(AUTORCC_EXECUTABLE CACHE)
- find_program(AUTORCC_EXECUTABLE rcc HINTS "${QT_PATH}/bin")
- mark_as_advanced(AUTORCC_EXECUTABLE) # Hiding from GUI
- set(Qt5Core_RCC_EXECUTABLE "${AUTORCC_EXECUTABLE}" CACHE FILEPATH "Qt's resource compiler, used by qt5_add_resources" FORCE)
- mark_as_advanced(Qt5Core_RCC_EXECUTABLE) # Hiding from GUI
- # LRELEASE executable
- unset(QT_LRELEASE_EXECUTABLE CACHE)
- find_program(QT_LRELEASE_EXECUTABLE lrelease HINTS "${QT_PATH}/bin")
- mark_as_advanced(QT_LRELEASE_EXECUTABLE) # Hiding from GUI
- if(NOT QT_LRELEASE_EXECUTABLE)
- message(FATAL_ERROR "Qt's lrelease executbale not found")
- endif()
- set(Qt5_LRELEASE_EXECUTABLE "${QT_LRELEASE_EXECUTABLE}" CACHE FILEPATH "Qt's lrelease executable, used by qt5_add_translation" FORCE)
- mark_as_advanced(Qt5_LRELEASE_EXECUTABLE) # Hiding from GUI
- #! ly_qt_uic_target: handles qt's ui files by injecting uic generation
- #
- # AUTOUIC has issues to detect changes in UIC files and trigger regeneration:
- # https://gitlab.kitware.com/cmake/cmake/-/issues/18741
- # So instead, we are going to manually wrap the files. We dont use qt5_wrap_ui because
- # it outputs to ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.h and we want to follow the
- # same folder structure that AUTOUIC uses
- #
- function(ly_qt_uic_target TARGET)
-
- get_target_property(all_ui_sources ${TARGET} SOURCES)
- list(FILTER all_ui_sources INCLUDE REGEX "^.*\\.ui$")
- if(NOT all_ui_sources)
- message(FATAL_ERROR "Target ${TARGET} contains AUTOUIC but doesnt have any .ui file")
- endif()
-
- if(AUTOGEN_BUILD_DIR)
- set(gen_dir ${AUTOGEN_BUILD_DIR})
- else()
- set(gen_dir ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_autogen/include)
- endif()
- foreach(ui_source ${all_ui_sources})
-
- get_filename_component(filename ${ui_source} NAME_WE)
- get_filename_component(dir ${ui_source} DIRECTORY)
- if(IS_ABSOLUTE ${dir})
- file(RELATIVE_PATH dir ${CMAKE_CURRENT_SOURCE_DIR} ${dir})
- endif()
- set(outfolder ${gen_dir}/${dir})
- set(outfile ${outfolder}/ui_${filename}.h)
- get_filename_component(infile ${ui_source} ABSOLUTE)
- file(MAKE_DIRECTORY ${outfolder})
- add_custom_command(OUTPUT ${outfile}
- COMMAND ${QT_UIC_EXECUTABLE} -o ${outfile} ${infile}
- MAIN_DEPENDENCY ${infile} VERBATIM
- COMMENT "UIC ${infile}"
- )
- set_source_files_properties(${infile} PROPERTIES SKIP_AUTOUIC TRUE)
- set_source_files_properties(${outfile} PROPERTIES
- SKIP_AUTOMOC TRUE
- SKIP_AUTOUIC TRUE
- GENERATED TRUE
- )
- list(APPEND all_ui_wrapped_sources ${outfile})
- endforeach()
- # Add files to the target
- target_sources(${TARGET} PRIVATE ${all_ui_wrapped_sources})
- source_group("Generated Files" FILES ${all_ui_wrapped_sources})
- # Add include directories relative to the generated folder
- # query for the property first to avoid the "NOTFOUND" in a list
- get_property(has_includes TARGET ${TARGET} PROPERTY INCLUDE_DIRECTORIES SET)
- if(has_includes)
- get_property(all_include_directories TARGET ${TARGET} PROPERTY INCLUDE_DIRECTORIES)
- foreach(dir ${all_include_directories})
- if(IS_ABSOLUTE ${dir})
- file(RELATIVE_PATH dir ${CMAKE_CURRENT_SOURCE_DIR} ${dir})
- endif()
- list(APPEND new_includes ${gen_dir}/${dir})
- endforeach()
- endif()
- list(APPEND new_includes ${gen_dir})
- target_include_directories(${TARGET} PRIVATE ${new_includes})
- endfunction()
- #! ly_add_translations: adds translations (ts) to a target.
- #
- # This wrapper will generate a qrc file with those translations and add the files under "prefix" and add them to
- # the indicated targets. These files will be added under the "Generated Files" filter
- #
- # \arg:TARGETS name of the targets that the translations will be added to
- # \arg:PREFIX prefix where the translation will be located within the qrc file
- # \arg:FILES translation files to add
- #
- function(ly_add_translations)
- set(options)
- set(oneValueArgs PREFIX)
- set(multiValueArgs TARGETS FILES)
- cmake_parse_arguments(ly_add_translations "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
- # Validate input arguments
- if(NOT ly_add_translations_TARGETS)
- message(FATAL_ERROR "You must provide at least one target")
- endif()
- if(NOT ly_add_translations_FILES)
- message(FATAL_ERROR "You must provide at least a translation file")
- endif()
- qt5_add_translation(TRANSLATED_FILES ${ly_add_translations_FILES})
- set(qrc_file_contents
- "<RCC>
- <qresource prefix=\"/${ly_add_translations_PREFIX}\">
- ")
- foreach(file ${TRANSLATED_FILES})
- get_filename_component(filename ${file} NAME)
- string(APPEND qrc_file_contents " <file>${filename}</file>
- ")
- endforeach()
- string(APPEND qrc_file_contents " </qresource>
- </RCC>
- ")
- set(qrc_file_path ${CMAKE_CURRENT_BINARY_DIR}/i18n_${ly_add_translations_PREFIX}.qrc)
- file(WRITE
- ${qrc_file_path}
- ${qrc_file_contents}
- )
- set_source_files_properties(
- ${TRANSLATED_FILES}
- ${qrc_file_path}
- PROPERTIES
- GENERATED TRUE
- SKIP_AUTORCC TRUE
- )
- qt5_add_resources(RESOURCE_FILE ${qrc_file_path})
- foreach(target ${ly_add_translations_TARGETS})
- target_sources(${target} PRIVATE "${TRANSLATED_FILES};${qrc_file_path};${RESOURCE_FILE}")
- endforeach()
- endfunction()
|