-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for a wayland variant of Qt for Linux
- Remove unnecessary wrapper scripts build-linux-aarch64.sh and build-linux-x86.sh - Add special build_config_wayland.json and Dockerfile.wayland to support the wayland variant - Update docker_build_qt_linux.sh to support the environment option 'ENABLE_QT_WAYLAND' which is set in the Dockerfile - Update docker_build_qt_linux.sh to support building the additional qtwayland package from source Signed-off-by: Steve Pham <[email protected]>
- Loading branch information
1 parent
11c082c
commit e653154
Showing
11 changed files
with
532 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
|
||
# 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 | ||
# | ||
|
||
# This docker file uses ubuntu 20.04 as the base image to install the dependencies to build Qt from source | ||
# | ||
|
||
FROM public.ecr.aws/ubuntu/ubuntu:20.04_stable | ||
|
||
WORKDIR /data/workspace | ||
|
||
# Initilize apt cache | ||
RUN apt-get clean && apt-get update | ||
|
||
# Setup time zone and locale data (necessary for SSL and HTTPS packages) | ||
RUN DEBIAN_FRONTEND="noninteractive" apt-get -y install tzdata locales keyboard-configuration | ||
|
||
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ | ||
dpkg-reconfigure --frontend=noninteractive locales && \ | ||
update-locale LANG=en_US.UTF-8 | ||
|
||
ENV LANG=en_US.UTF-8 | ||
ENV ENABLE_QT_WAYLAND=1 | ||
|
||
# Install the development packages needed to build Qt from source | ||
RUN apt-get install -y qtbase5-dev \ | ||
build-essential \ | ||
perl \ | ||
python3 \ | ||
git \ | ||
'^libxcb.*-dev' \ | ||
libx11-xcb-dev \ | ||
libglu1-mesa-dev \ | ||
libxrender-dev \ | ||
libxi-dev \ | ||
libxkbcommon-dev \ | ||
libxkbcommon-x11-dev \ | ||
libgbm-dev \ | ||
libxext-dev \ | ||
libfontconfig1-dev \ | ||
libtiff-dev \ | ||
libwayland-dev \ | ||
libwayland-egl1-mesa \ | ||
libwayland-server0 \ | ||
libgles2-mesa-dev | ||
|
||
# Prepare a target folder within the container to install the build artifacts tp | ||
RUN mkdir -p /data/workspace/qt | ||
|
||
RUN git clone --single-branch --recursive --branch v5.15.1 git://code.qt.io/qt/qtwayland.git && \ | ||
ln -s /data/workspace/qtwayland/include/QtWaylandCompositor/5.15.1/QtWaylandCompositor/private/qwayland-server-qt-texture-sharing-unstable-v1.h /data/workspace/qtwayland/src/compositor/qwayland-server-qt-texture-sharing-unstable-v1.h && \ | ||
ln -s /data/workspace/qtwayland/include/QtWaylandCompositor/5.15.1/QtWaylandCompositor/private/wayland-qt-texture-sharing-unstable-v1-server-protocol.h /data/workspace/qtwayland/src/compositor/wayland-qt-texture-sharing-unstable-v1-server-protocol.h | ||
|
||
# Copy the build script specific to this Docker script in order to execute the build | ||
COPY docker_build_qt_linux.sh /data/workspace/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,288 @@ | ||
# | ||
# 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() |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.