summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2022-09-05 20:10:20 +0200
committerJoerg Bornemann <joerg.bornemann@qt.io>2022-09-15 12:55:23 +0200
commit1b5462c2acc2a543a41fd0a6a9d15df43e139fbc (patch)
tree67ca5fcfffaffe07d12ddaf7baf70da9b8e293d8
parentc9c04291f5f96ff885f7caae6c15ce9bc1377fcc (diff)
CMake: Introduce qt_deploy_translations
Add the command qt_deploy_translations to the CMake deployment API. This can be used to deploy a set of Qt translations. This command is supposed to be called by the generic deployment tool in a future commit. [ChangeLog][CMake] Added qt_deploy_translations for deploying Qt translation catalogs in user projects. Change-Id: I4492a5042970cf89b2be2ed0c34521c7af904771 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
-rw-r--r--src/corelib/Qt6CoreDeploySupport.cmake144
-rw-r--r--src/corelib/Qt6CoreMacros.cmake6
-rw-r--r--src/corelib/doc/src/cmake/cmake-deploy-variables.qdoc43
-rw-r--r--src/corelib/doc/src/cmake/qt_deploy_translations.qdoc76
4 files changed, 264 insertions, 5 deletions
diff --git a/src/corelib/Qt6CoreDeploySupport.cmake b/src/corelib/Qt6CoreDeploySupport.cmake
index 7c307d18e0..c2ff58a669 100644
--- a/src/corelib/Qt6CoreDeploySupport.cmake
+++ b/src/corelib/Qt6CoreDeploySupport.cmake
@@ -394,3 +394,147 @@ function(_qt_internal_show_skip_runtime_deploy_message qt_build_type_string)
"this target platform (${__QT_DEPLOY_SYSTEM_NAME}, ${qt_build_type_string})."
)
endfunction()
+
+# This function is currently in Technical Preview.
+# Its signature and behavior might change.
+function(qt6_deploy_translations)
+ set(no_value_options VERBOSE)
+ set(single_value_options
+ LCONVERT
+ )
+ set(multi_value_options
+ CATALOGS
+ LOCALES
+ )
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ "${no_value_options}" "${single_value_options}" "${multi_value_options}"
+ )
+
+ set(verbose OFF)
+ if(arg_VERBOSE OR __QT_DEPLOY_VERBOSE)
+ set(verbose ON)
+ endif()
+
+ if(arg_CATALOGS)
+ set(catalogs ${arg_CATALOGS})
+ else()
+ set(catalogs qt qtbase)
+
+ # Find the translations that belong to the Qt modules that are used by the project.
+ # "Used by the project" means just all modules that are pulled in via find_package for now.
+ set(modules ${__QT_DEPLOY_ALL_MODULES_FOUND_VIA_FIND_PACKAGE})
+
+ set(module_catalog_mapping
+ "Bluetooth|Nfc" qtconnectivity
+ "Help" qt_help
+ "Multimedia(Widgets|QuickPrivate)?" qtmultimedia
+ "Qml|Quick" qtdeclarative
+ "SerialPort" qtserialport
+ "WebEngine" qtwebengine
+ "WebSockets" qtwebsockets
+ )
+ list(LENGTH module_catalog_mapping max_i)
+ math(EXPR max_i "${max_i} - 1")
+ foreach(module IN LISTS modules)
+ foreach(i RANGE 0 ${max_i} 2)
+ list(GET module_catalog_mapping ${i} module_rex)
+ if(NOT module MATCHES "^${module_rex}")
+ continue()
+ endif()
+ math(EXPR k "${i} + 1")
+ list(GET module_catalog_mapping ${k} catalog)
+ list(APPEND catalogs ${catalog})
+ endforeach()
+ endforeach()
+ endif()
+
+ get_filename_component(qt_translations_dir "${__QT_DEPLOY_QT_INSTALL_TRANSLATIONS}" ABSOLUTE
+ BASE_DIR "${__QT_DEPLOY_QT_INSTALL_PREFIX}"
+ )
+ set(locales ${arg_LOCALES})
+ if(NOT locales)
+ file(GLOB locales RELATIVE "${qt_translations_dir}" "${qt_translations_dir}/*.qm")
+ list(TRANSFORM locales REPLACE "\\.qm$" "")
+ list(TRANSFORM locales REPLACE "^qt_help" "qt-help")
+ list(TRANSFORM locales REPLACE "^[^_]+" "")
+ list(TRANSFORM locales REPLACE "^_" "")
+ list(REMOVE_DUPLICATES locales)
+ endif()
+
+ # Ensure existence of the output directory.
+ set(output_dir "${QT_DEPLOY_PREFIX}/${QT_DEPLOY_TRANSLATIONS_DIR}")
+ if(NOT EXISTS "${output_dir}")
+ file(MAKE_DIRECTORY "${output_dir}")
+ endif()
+
+ # Locate lconvert.
+ if(arg_LCONVERT)
+ set(lconvert "${arg_LCONVERT}")
+ else()
+ set(lconvert "${__QT_DEPLOY_QT_INSTALL_PREFIX}/${__QT_DEPLOY_QT_INSTALL_BINS}/lconvert")
+ if(CMAKE_HOST_WIN32)
+ string(APPEND lconvert ".exe")
+ endif()
+ if(NOT EXISTS ${lconvert})
+ message(STATUS "lconvert was not found. Skipping deployment of translations.")
+ return()
+ endif()
+ endif()
+
+ # Find the .qm files for the selected locales
+ if(verbose)
+ message(STATUS "Looking for translations in ${qt_translations_dir}")
+ endif()
+ foreach(locale IN LISTS locales)
+ set(qm_files "")
+ foreach(catalog IN LISTS catalogs)
+ set(qm_file "${catalog}_${locale}.qm")
+ if(EXISTS "${qt_translations_dir}/${qm_file}")
+ list(APPEND qm_files ${qm_file})
+ endif()
+ endforeach()
+
+ if(NOT qm_files)
+ message(WARNING "No translations found for requested locale '${locale}'.")
+ continue()
+ endif()
+
+ if(verbose)
+ foreach(qm_file IN LISTS qm_files)
+ message(STATUS "found translation file: ${qm_file}")
+ endforeach()
+ endif()
+
+ # Merge the .qm files into one qt_${locale}.qm file.
+ set(output_file_name "qt_${locale}.qm")
+ set(output_file_path "${output_dir}/${output_file_name}")
+ message(STATUS "Creating: ${output_file_path}")
+ set(extra_options)
+ if(verbose)
+ list(APPEND extra_options COMMAND_ECHO STDOUT)
+ endif()
+ execute_process(
+ COMMAND ${lconvert} -if qm -o ${output_file_path} ${qm_files}
+ WORKING_DIRECTORY ${qt_translations_dir}
+ RESULT_VARIABLE process_result
+ ${extra_options}
+ )
+ if(NOT process_result EQUAL "0")
+ if(process_result MATCHES "^[0-9]+$")
+ message(WARNING "lconvert failed with exit code ${process_result}.")
+ else()
+ message(WARNING "lconvert failed: ${process_result}.")
+ endif()
+ endif()
+ endforeach()
+endfunction()
+
+if(NOT __QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
+ function(qt_deploy_translations)
+ if(__QT_DEFAULT_MAJOR_VERSION EQUAL 6)
+ qt6_deploy_translations(${ARGV})
+ else()
+ message(FATAL_ERROR "qt_deploy_translations() is only available in Qt 6.")
+ endif()
+ endfunction()
+endif()
diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake
index 3bea0f135b..c6d0d765e8 100644
--- a/src/corelib/Qt6CoreMacros.cmake
+++ b/src/corelib/Qt6CoreMacros.cmake
@@ -2464,6 +2464,9 @@ endif()
if(NOT QT_DEPLOY_QML_DIR)
set(QT_DEPLOY_QML_DIR \"qml\")
endif()
+if(NOT QT_DEPLOY_TRANSLATIONS_DIR)
+ set(QT_DEPLOY_TRANSLATIONS_DIR \"translations\")
+endif()
if(NOT QT_DEPLOY_PREFIX)
set(QT_DEPLOY_PREFIX \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}\")
endif()
@@ -2484,7 +2487,9 @@ set(__QT_NO_CREATE_VERSIONLESS_FUNCTIONS \"${QT_NO_CREATE_VERSIONLESS_FUNCTIONS}
set(__QT_DEFAULT_MAJOR_VERSION \"${QT_DEFAULT_MAJOR_VERSION}\")
set(__QT_DEPLOY_QT_ADDITIONAL_PACKAGES_PREFIX_PATH \"${QT_ADDITIONAL_PACKAGES_PREFIX_PATH}\")
set(__QT_DEPLOY_QT_INSTALL_PREFIX \"${QT6_INSTALL_PREFIX}\")
+set(__QT_DEPLOY_QT_INSTALL_BINS \"${QT6_INSTALL_BINS}\")
set(__QT_DEPLOY_QT_INSTALL_PLUGINS \"${QT6_INSTALL_PLUGINS}\")
+set(__QT_DEPLOY_QT_INSTALL_TRANSLATIONS \"${QT6_INSTALL_TRANSLATIONS}\")
set(__QT_DEPLOY_PLUGINS \"\")
# Define the CMake commands to be made available during deployment.
@@ -2640,6 +2645,7 @@ function(qt6_generate_deploy_script)
set(boiler_plate "include(${QT_DEPLOY_SUPPORT})
include(\"\${CMAKE_CURRENT_LIST_DIR}/${arg_TARGET}-plugins${config_infix}.cmake\" OPTIONAL)
+set(__QT_DEPLOY_ALL_MODULES_FOUND_VIA_FIND_PACKAGE \"${QT_ALL_MODULES_FOUND_VIA_FIND_PACKAGE}\")
")
list(TRANSFORM arg_CONTENT REPLACE "\\$" "\$")
file(GENERATE OUTPUT ${file_name} CONTENT "${boiler_plate}${arg_CONTENT}")
diff --git a/src/corelib/doc/src/cmake/cmake-deploy-variables.qdoc b/src/corelib/doc/src/cmake/cmake-deploy-variables.qdoc
index b10de9dc3b..8182dd74e4 100644
--- a/src/corelib/doc/src/cmake/cmake-deploy-variables.qdoc
+++ b/src/corelib/doc/src/cmake/cmake-deploy-variables.qdoc
@@ -49,7 +49,7 @@ install location and just use the prefix-relative \c{QT_DEPLOY_..._DIR}
variables.
\sa QT_DEPLOY_SUPPORT, QT_DEPLOY_BIN_DIR, QT_DEPLOY_LIB_DIR,
- QT_DEPLOY_PLUGINS_DIR, QT_DEPLOY_QML_DIR
+ QT_DEPLOY_PLUGINS_DIR, QT_DEPLOY_QML_DIR, QT_DEPLOY_TRANSLATIONS_DIR
*/
/*!
@@ -90,7 +90,7 @@ should not be used for that scenario.
\include cmake-deploy-runtime-dependencies.qdocinc
\sa QT_DEPLOY_SUPPORT, QT_DEPLOY_PREFIX, QT_DEPLOY_LIB_DIR,
- QT_DEPLOY_PLUGINS_DIR, QT_DEPLOY_QML_DIR
+ QT_DEPLOY_PLUGINS_DIR, QT_DEPLOY_QML_DIR, QT_DEPLOY_TRANSLATIONS_DIR
*/
/*!
@@ -132,7 +132,7 @@ should not be used for that scenario.
\include cmake-deploy-modified-variable-values.qdocinc
\sa QT_DEPLOY_SUPPORT, QT_DEPLOY_PREFIX, QT_DEPLOY_BIN_DIR,
- QT_DEPLOY_PLUGINS_DIR, QT_DEPLOY_QML_DIR
+ QT_DEPLOY_PLUGINS_DIR, QT_DEPLOY_QML_DIR, QT_DEPLOY_TRANSLATIONS_DIR
*/
/*!
@@ -168,7 +168,7 @@ bundle contents.
\include cmake-deploy-modified-variable-values.qdocinc
\sa QT_DEPLOY_SUPPORT, QT_DEPLOY_PREFIX, QT_DEPLOY_BIN_DIR, QT_DEPLOY_LIB_DIR,
- QT_DEPLOY_QML_DIR
+ QT_DEPLOY_QML_DIR, QT_DEPLOY_TRANSLATIONS_DIR
*/
/*!
@@ -206,5 +206,38 @@ to be deployed to different locations within the app bundle.
\include cmake-deploy-modified-variable-values.qdocinc
\sa QT_DEPLOY_SUPPORT, QT_DEPLOY_PREFIX, QT_DEPLOY_BIN_DIR, QT_DEPLOY_LIB_DIR,
- QT_DEPLOY_PLUGINS_DIR
+ QT_DEPLOY_PLUGINS_DIR, QT_DEPLOY_TRANSLATIONS_DIR
+*/
+
+/*!
+\page cmake-variable-QT_DEPLOY_TRANSLATIONS_DIR.html
+\ingroup cmake-variables-qtcore
+
+\title QT_DEPLOY_TRANSLATIONS_DIR
+\target cmake-variable-QT_DEPLOY_TRANSLATIONS_DIR
+
+\summary {Prefix-relative subdirectory for deploying Qt translations on some target platforms.}
+
+\include cmake-deploy-var-usage.qdocinc
+
+\cmakevariablesince 6.5
+\preliminarycmakevariable
+
+Projects should use \c QT_DEPLOY_TRANSLATIONS_DIR in their deploy scripts to
+avoid hard-coding a particular directory under which to deploy translations.
+
+\c QT_DEPLOY_TRANSLATIONS_DIR defaults to the value \c{translations}. To change
+the value of \c QT_DEPLOY_TRANSLATIONS_DIR, set it in the project deployment
+script before \c QT_DEPLOY_SUPPORT is included.
+
+The \c QT_DEPLOY_TRANSLATIONS_DIR path is relative to \l{QT_DEPLOY_PREFIX}.
+
+This variable is not meaningful when deploying on macOS or Windows.
+
+\section1 Example
+
+\include cmake-deploy-modified-variable-values.qdocinc
+
+\sa QT_DEPLOY_SUPPORT, QT_DEPLOY_PREFIX, QT_DEPLOY_BIN_DIR, QT_DEPLOY_LIB_DIR,
+ QT_DEPLOY_PLUGINS_DIR, QT_DEPLOY_QML_DIR
*/
diff --git a/src/corelib/doc/src/cmake/qt_deploy_translations.qdoc b/src/corelib/doc/src/cmake/qt_deploy_translations.qdoc
new file mode 100644
index 0000000000..87ef7cd2fc
--- /dev/null
+++ b/src/corelib/doc/src/cmake/qt_deploy_translations.qdoc
@@ -0,0 +1,76 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+\page qt_deploy_translations.html
+\ingroup cmake-commands-qtcore
+
+\title qt_deploy_translations
+\target qt_deploy_translations
+
+\summary {Deploy Qt translations needed by an executable.}
+
+\include cmake-find-package-core.qdocinc
+
+Unlike most other CMake commands provided by Qt, \c{qt_deploy_translations()}
+can only be called from a deployment script. It cannot be called directly by the
+project during the configure stage.
+
+\cmakecommandsince 6.5
+\preliminarycmakecommand
+\note This command does not usually need to be called directly. It is used
+ internally by other higher level commands, but projects wishing to
+ implement more customized deployment logic may find it useful.
+
+\section1 Synopsis
+
+\badcode
+qt_deploy_translations(
+ [CATALOGS catalogs]
+ [LOCALES locales]
+ [LCONVERT lconvert_executable]
+ [VERBOSE]
+)
+\endcode
+
+\section1 Description
+
+When installing an application, it may be desirable to also install the
+translations that belong to the used Qt modules. The \c qt_deploy_translations
+command collects the necessary \c{.qm} file from the Qt installation and
+compiles them into one \c{qt_${language}.qm} file per language. The \c{.qm}
+files are installed into \c{QT_DEPLOY_TRANSLATIONS_DIR}.
+
+\section1 Arguments
+
+The \c LOCALES argument specifies for which locales translations should be
+deployed. This is a list of language/region combinations as described in
+\l{Changing the Target Locale}{Qt Linguist's manual for translators}. Examples
+for valid locales are: \c{de}, \c{pl}, or \c{pt_BR}.
+
+If \c LOCALES is omitted, then all available locales are deployed.
+
+The \c CATALOGS argument specifies a list of \l{Available
+Catalogs}{translation catalogs} to be deployed. If this argument is
+omitted, then all catalogs are deployed that belong to any Qt module
+that is used in the project via \c{find_package}.
+
+The \c LCONVERT argument specifies the \c lconvert executable that is used to
+combine the catalogs. By default, the Qt installation's \c lconvert is used.
+
+For debugging purposed, the \c VERBOSE argument can be set to turn on diagnostic
+messages.
+
+\sa QT_DEPLOY_TRANSLATIONS_DIR
+
+\section1 Example
+
+The following example deploys Danish and German translations of the Qt
+libraries.
+
+\badcode
+qt_deploy_translations(
+ LOCALES da de
+)
+\endcode
+*/