aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2022-01-22 01:01:29 +0200
committerGitHub <noreply@github.com>2022-01-22 01:01:29 +0200
commit4316b71017e1f4ca0d3d65f675e6cdceb3330d97 (patch)
tree69070743b7a206aaa11947f31cfec70762f3de97 /mesonbuild
parent2a992526045b702a8ab72968c98fef9f9e189d2b (diff)
parent02fb0c3f8bb60d88998c8a8c7d090ecc864ed04c (diff)
downloadmeson-4316b71017e1f4ca0d3d65f675e6cdceb3330d97.zip
meson-4316b71017e1f4ca0d3d65f675e6cdceb3330d97.tar.gz
meson-4316b71017e1f4ca0d3d65f675e6cdceb3330d97.tar.bz2
Merge pull request #9742 from ximion/wip/itstool
i18n: Add support for joining XML localization via itstool
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/modules/i18n.py81
-rw-r--r--mesonbuild/scripts/itstool.py82
2 files changed, 162 insertions, 1 deletions
diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py
index 5be7eb0..d92e334 100644
--- a/mesonbuild/modules/i18n.py
+++ b/mesonbuild/modules/i18n.py
@@ -59,6 +59,20 @@ if T.TYPE_CHECKING:
languages: T.List[str]
preset: T.Optional[str]
+ class ItsJoinFile(TypedDict):
+
+ input: T.List[T.Union[
+ str, build.BuildTarget, build.CustomTarget, build.CustomTargetIndex,
+ build.ExtractedObjects, build.GeneratedList, ExternalProgram,
+ mesonlib.File]]
+ output: T.List[str]
+ build_by_default: bool
+ install: bool
+ install_dir: T.List[T.Union[str, bool]]
+ install_tag: T.List[str]
+ its_files: T.List[str]
+ mo_targets: T.List[T.Union[build.BuildTarget, build.CustomTarget, build.CustomTargetIndex]]
+
_ARGS: KwargInfo[T.List[str]] = KwargInfo(
'args',
@@ -115,6 +129,7 @@ class I18nModule(ExtensionModule):
self.methods.update({
'merge_file': self.merge_file,
'gettext': self.gettext,
+ 'itstool_join': self.itstool_join,
})
@staticmethod
@@ -122,6 +137,10 @@ class I18nModule(ExtensionModule):
mlog.warning('Gettext not found, all translation targets will be ignored.', once=True)
@staticmethod
+ def noitstool_error() -> T.NoReturn:
+ raise mesonlib.MesonException('Did not find itstool. Please install it to continue.')
+
+ @staticmethod
def _get_data_dirs(state: 'ModuleState', dirs: T.Iterable[str]) -> T.List[str]:
"""Returns source directories of relative paths"""
src_dir = path.join(state.environment.get_source_dir(), state.subdir)
@@ -184,7 +203,7 @@ class I18nModule(ExtensionModule):
return ModuleReturnValue(ct, [ct])
- @typed_pos_args('i81n.gettex', str)
+ @typed_pos_args('i81n.gettext', str)
@typed_kwargs(
'i18n.gettext',
_ARGS,
@@ -269,5 +288,65 @@ class I18nModule(ExtensionModule):
return ModuleReturnValue([gmotargets, pottarget, updatepotarget], targets)
+ @FeatureNew('i18n.itstool_join', '0.61.0')
+ @noPosargs
+ @typed_kwargs(
+ 'i18n.itstool_join',
+ CT_BUILD_BY_DEFAULT,
+ CT_INPUT_KW,
+ CT_INSTALL_DIR_KW,
+ CT_INSTALL_TAG_KW,
+ CT_OUTPUT_KW,
+ INSTALL_KW,
+ _ARGS.evolve(),
+ KwargInfo('its_files', ContainerTypeInfo(list, str)),
+ KwargInfo('mo_targets', ContainerTypeInfo(list, build.CustomTarget), required=True),
+ )
+ def itstool_join(self, state: 'ModuleState', args: T.List['TYPE_var'], kwargs: 'ItsJoinFile') -> ModuleReturnValue:
+ if not shutil.which('itstool'):
+ self.noitstool_error()
+ mo_targets = kwargs['mo_targets']
+ its_files = kwargs.get('its_files', [])
+
+ mo_fnames = []
+ for target in mo_targets:
+ mo_fnames.append(path.join(target.get_subdir(), target.get_outputs()[0]))
+
+ command: T.List[T.Union[str, build.BuildTarget, build.CustomTarget,
+ build.CustomTargetIndex, 'ExternalProgram', mesonlib.File]] = []
+ command.extend(state.environment.get_build_command())
+ command.extend([
+ '--internal', 'itstool', 'join',
+ '-i', '@INPUT@',
+ '-o', '@OUTPUT@'
+ ])
+ if its_files:
+ for fname in its_files:
+ if not path.isabs(fname):
+ fname = path.join(state.environment.source_dir, state.subdir, fname)
+ command.extend(['--its', fname])
+ command.extend(mo_fnames)
+
+ build_by_default = kwargs['build_by_default']
+ if build_by_default is None:
+ build_by_default = kwargs['install']
+
+ real_kwargs = {
+ 'build_by_default': build_by_default,
+ 'command': command,
+ 'depends': mo_targets,
+ 'install': kwargs['install'],
+ 'install_dir': kwargs['install_dir'],
+ 'output': kwargs['output'],
+ 'input': kwargs['input'],
+ 'install_tag': kwargs['install_tag'],
+ }
+
+ ct = build.CustomTarget('', state.subdir, state.subproject,
+ T.cast(T.Dict[str, T.Any], real_kwargs))
+
+ return ModuleReturnValue(ct, [ct])
+
+
def initialize(interp: 'Interpreter') -> I18nModule:
return I18nModule(interp)
diff --git a/mesonbuild/scripts/itstool.py b/mesonbuild/scripts/itstool.py
new file mode 100644
index 0000000..fa3b0fa
--- /dev/null
+++ b/mesonbuild/scripts/itstool.py
@@ -0,0 +1,82 @@
+# Copyright 2016 The Meson development team
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import argparse
+import subprocess
+import tempfile
+import shutil
+import typing as T
+
+parser = argparse.ArgumentParser()
+parser.add_argument('command')
+parser.add_argument('--build-dir', default='')
+parser.add_argument('-i', '--input', default='')
+parser.add_argument('-o', '--output', default='')
+parser.add_argument('--its', action='append', default=[])
+parser.add_argument('mo_files', nargs='+')
+
+
+def run_join(build_dir: str, its_files: T.List[str], mo_files: T.List[str], in_fname: str, out_fname: str) -> int:
+ if not mo_files:
+ print('No mo files specified to use for translation.')
+ return 1
+
+ with tempfile.TemporaryDirectory(prefix=os.path.basename(in_fname), dir=build_dir) as tmp_dir:
+ # copy mo files to have the right names so itstool can infer their locale
+ locale_mo_files = []
+ for mo_file in mo_files:
+ if not os.path.exists(mo_file):
+ print('Could not find mo file {}'.format(mo_file))
+ return 1
+ if not mo_file.endswith('.mo'):
+ print('File is not a mo file: {}'.format(mo_file))
+ return 1
+ # determine locale of this mo file
+ parts = mo_file.partition('LC_MESSAGES')
+ if parts[0].endswith((os.sep, '/')):
+ locale = os.path.basename(parts[0][:-1])
+ else:
+ locale = os.path.basename(parts[0])
+ tmp_mo_fname = os.path.join(tmp_dir, locale + '.mo')
+ shutil.copy(mo_file, tmp_mo_fname)
+ locale_mo_files.append(tmp_mo_fname)
+
+ cmd = ['itstool']
+ if its_files:
+ for fname in its_files:
+ cmd.extend(['-i', fname])
+ cmd.extend(['-j', in_fname,
+ '-o', out_fname])
+ cmd.extend(locale_mo_files)
+
+ return subprocess.call(cmd)
+
+
+def run(args: T.List[str]) -> int:
+ options = parser.parse_args(args)
+ command = options.command
+ build_dir = os.environ.get('MESON_BUILD_ROOT', os.getcwd())
+ if options.build_dir:
+ build_dir = options.build_dir
+
+ if command == 'join':
+ return run_join(build_dir,
+ options.its,
+ options.mo_files,
+ options.input,
+ options.output)
+ else:
+ print('Unknown subcommand.')
+ return 1