Repository navigation
Expand file tree
/
Copy pathUpdateTranslations.cmake
More file actions
143 lines (116 loc) · 6.94 KB
/
Copy pathUpdateTranslations.cmake
File metadata and controls
143 lines (116 loc) · 6.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# Creates or updates the translation sources (.ts) of one or more languages by running lupdate over
# the source directories. Texts already translated in an existing .ts are preserved, only new texts
# are added (and texts not found anymore are kept as obsolete).
#
# It runs as a script through the target update_ts (see TranslationConfs.cmake), which provides the
# variables below. The names of the source folders are passed by the target, from the variables the build
# uses, because this script can't include the files that define them (they use commands that are not
# available in script mode). The language can be overridden by the environment variable PGM_TS_LANG.
#
# PGM_SOURCE_DIR source root
# LUPDATE path to lupdate
# PGM_APPS_DIR, PGM_LIBS_DIR folders of the applications and libraries, relative to the source root
# PGM_PRIV_CORE_DIR folder of the private core code (optional in the source tree)
# PGM_PRIV_PLUGINS_DIR folder of the private plugins (optional in the source tree)
# PGM_TS_LANG list of language codes in the form xx or xx_XX (e.g. pt_BR, fr_FR);
# the code is also the base name of the .ts files:
# - the main dictionary is assets/lang/<lang>.ts and gathers the applications, the libraries, the
# private core code (if it exists) and the executables of the private plugins folder, i.e., the
# folders that are not plugins (like pgmodeler-pi), since they load the main dictionary;
# - each plugin in the private plugins folder (if it exists) has its own dictionary in
# <plugin>/lang/<lang>.ts and gathers the plugin's folder plus the src folder of the private plugins,
# which is compiled into every plugin.
cmake_minimum_required(VERSION 3.16)
# The language set in the environment takes precedence. Without it the default language, the one
# configured in PGM_TS_LANG, is updated and a warning is shown at the end
set(_LANG_FROM_ENV OFF)
if(DEFINED ENV{PGM_TS_LANG} AND NOT "$ENV{PGM_TS_LANG}" STREQUAL "")
set(PGM_TS_LANG "$ENV{PGM_TS_LANG}")
set(_LANG_FROM_ENV ON)
endif()
foreach(_VAR PGM_SOURCE_DIR LUPDATE PGM_APPS_DIR PGM_LIBS_DIR PGM_PRIV_CORE_DIR PGM_PRIV_PLUGINS_DIR PGM_TS_LANG)
if(NOT DEFINED ${_VAR} OR "${${_VAR}}" STREQUAL "")
message(FATAL_ERROR "UpdateTranslations: the variable ${_VAR} must be provided.")
endif()
endforeach()
# A relative source root (e.g. -DPGM_SOURCE_DIR=.) is taken from the current directory. It must be
# absolute because file(GLOB ... RELATIVE) doesn't work with relative paths
get_filename_component(PGM_SOURCE_DIR "${PGM_SOURCE_DIR}" ABSOLUTE)
# The texts marked with PGM_TR2 are recognized as an alias of QT_TRANSLATE_NOOP
set(_ALIAS "QT_TRANSLATE_NOOP+=PGM_TR2")
# Folders of the private plugins that don't have a dictionary of their own: the plugin template and any
# folder that is not a loadable plugin (the ones that don't call pgm_install_plugin, e.g. the pgmodeler-pi
# executable, or have no CMakeLists.txt). The executables (pgm_add_executable) are part of the main dictionary
set(_EXCLUDED_PLUGINS templateplugin)
function(pgm_run_lupdate TS_FILE LOCATIONS LANG)
# The directory of the .ts must exist, lupdate creates the file but not the folder
get_filename_component(_TS_DIR ${TS_FILE} DIRECTORY)
file(MAKE_DIRECTORY ${_TS_DIR})
execute_process(
COMMAND ${LUPDATE} ${ARGN} -recursive -locations ${LOCATIONS}
-tr-function-alias ${_ALIAS}
-source-language en_US -target-language ${LANG}
-ts ${TS_FILE}
WORKING_DIRECTORY ${PGM_SOURCE_DIR}
RESULT_VARIABLE _RES)
if(NOT _RES EQUAL 0)
message(FATAL_ERROR "UpdateTranslations: lupdate failed for ${TS_FILE} (exit code ${_RES}).")
endif()
endfunction()
foreach(_LANG ${PGM_TS_LANG})
# xx or xx_XX (also accepting a script, e.g. zh_Hans or zh_Hans_CN)
if(NOT _LANG MATCHES "^[a-z][a-z][a-z]?(_[A-Z][A-Za-z][A-Za-z]?[A-Za-z]?)*$")
message(FATAL_ERROR "UpdateTranslations: invalid language code `${_LANG}'. Use xx or xx_XX, e.g. pt_BR or fr_FR.")
endif()
message(STATUS "Updating the ${_LANG} dictionaries...")
# Main dictionary
set(_MAIN_DIRS ${PGM_APPS_DIR} ${PGM_LIBS_DIR})
if(EXISTS ${PGM_SOURCE_DIR}/${PGM_PRIV_CORE_DIR})
list(APPEND _MAIN_DIRS ${PGM_PRIV_CORE_DIR})
endif()
# The executables in the private plugins folder load the main dictionary, so their texts are gathered in it
if(EXISTS ${PGM_SOURCE_DIR}/${PGM_PRIV_PLUGINS_DIR})
file(GLOB _PRIV_DIRS LIST_DIRECTORIES true RELATIVE ${PGM_SOURCE_DIR}/${PGM_PRIV_PLUGINS_DIR}
${PGM_SOURCE_DIR}/${PGM_PRIV_PLUGINS_DIR}/*)
list(SORT _PRIV_DIRS)
foreach(_DIR ${_PRIV_DIRS})
set(_CMAKELISTS ${PGM_SOURCE_DIR}/${PGM_PRIV_PLUGINS_DIR}/${_DIR}/CMakeLists.txt)
if(NOT _DIR IN_LIST _EXCLUDED_PLUGINS AND EXISTS ${_CMAKELISTS})
file(READ ${_CMAKELISTS} _CONTENTS)
if(_CONTENTS MATCHES "pgm_add_executable\\(")
list(APPEND _MAIN_DIRS ${PGM_PRIV_PLUGINS_DIR}/${_DIR})
endif()
endif()
endforeach()
endif()
# The file locations are omitted in the main dictionary because it lives in the public repository
# and gathers texts of private code too
message(STATUS "assets/lang/${_LANG}.ts (${_MAIN_DIRS})")
pgm_run_lupdate(${PGM_SOURCE_DIR}/assets/lang/${_LANG}.ts none ${_LANG} ${_MAIN_DIRS})
# Private plugins dictionaries
if(EXISTS ${PGM_SOURCE_DIR}/${PGM_PRIV_PLUGINS_DIR})
file(GLOB _PLUGIN_DIRS LIST_DIRECTORIES true RELATIVE ${PGM_SOURCE_DIR}/${PGM_PRIV_PLUGINS_DIR}
${PGM_SOURCE_DIR}/${PGM_PRIV_PLUGINS_DIR}/*)
list(SORT _PLUGIN_DIRS)
if(NOT _PLUGIN_DIRS)
message(WARNING "UpdateTranslations: no folder found in ${PGM_SOURCE_DIR}/${PGM_PRIV_PLUGINS_DIR}.")
endif()
foreach(_PLUGIN ${_PLUGIN_DIRS})
set(_CMAKELISTS ${PGM_SOURCE_DIR}/${PGM_PRIV_PLUGINS_DIR}/${_PLUGIN}/CMakeLists.txt)
if(_PLUGIN IN_LIST _EXCLUDED_PLUGINS OR NOT EXISTS ${_CMAKELISTS})
continue()
endif()
file(READ ${_CMAKELISTS} _CONTENTS)
if(NOT _CONTENTS MATCHES "pgm_install_plugin\\(")
continue()
endif()
message(STATUS "${PGM_PRIV_PLUGINS_DIR}/${_PLUGIN}/lang/${_LANG}.ts")
pgm_run_lupdate(${PGM_SOURCE_DIR}/${PGM_PRIV_PLUGINS_DIR}/${_PLUGIN}/lang/${_LANG}.ts relative ${_LANG}
${PGM_PRIV_PLUGINS_DIR}/${_PLUGIN} ${PGM_PRIV_PLUGINS_DIR}/src)
endforeach()
endif()
endforeach()
if(NOT _LANG_FROM_ENV)
message(WARNING "The environment variable PGM_TS_LANG was not provided: the default translation (${PGM_TS_LANG}) was updated instead. "
"To update another language run, e.g.: PGM_TS_LANG=fr_FR cmake --build <build dir> --target update_ts")
endif()