aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/modules/i18n.py
diff options
context:
space:
mode:
authorEli Schwartz <eschwartz@archlinux.org>2022-03-05 21:10:06 -0500
committerEli Schwartz <eschwartz@archlinux.org>2022-03-06 11:09:47 -0500
commit08928821ec00bb7e74cbf791e1f42eefd134379e (patch)
treedfe42fe2cc48b195f976f0954315d27919f37560 /mesonbuild/modules/i18n.py
parent768616b0f8c0a0349e84517b51b1b8e51c79d6b6 (diff)
downloadmeson-08928821ec00bb7e74cbf791e1f42eefd134379e.zip
meson-08928821ec00bb7e74cbf791e1f42eefd134379e.tar.gz
meson-08928821ec00bb7e74cbf791e1f42eefd134379e.tar.bz2
i18n module: detect gettext tools at configure time
Use this instead of shutil.which to detect whether they will be available, and pass the ExternalProgram object to CustomTarget invocations, or else make use of the new functionality to specify the correct program path in wrapper scripts. Drop duplicate reporting for itstool missing. Since we use find_program in required mode, its absence is already fatal, and already has a really good error description.
Diffstat (limited to 'mesonbuild/modules/i18n.py')
-rw-r--r--mesonbuild/modules/i18n.py40
1 files changed, 27 insertions, 13 deletions
diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py
index 210dd93..1eeb9ad 100644
--- a/mesonbuild/modules/i18n.py
+++ b/mesonbuild/modules/i18n.py
@@ -11,9 +11,9 @@
# 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.
+from __future__ import annotations
from os import path
-import shutil
import typing as T
from . import ExtensionModule, ModuleReturnValue
@@ -131,16 +131,19 @@ class I18nModule(ExtensionModule):
'gettext': self.gettext,
'itstool_join': self.itstool_join,
})
+ self.tools: T.Dict[str, T.Optional[ExternalProgram]] = {
+ 'itstool': None,
+ 'msgfmt': None,
+ 'msginit': None,
+ 'msgmerge': None,
+ 'xgettext': None,
+ }
@staticmethod
def nogettext_warning() -> None:
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)
@@ -162,7 +165,9 @@ class I18nModule(ExtensionModule):
KwargInfo('type', str, default='xml', validator=in_set_validator({'xml', 'desktop'})),
)
def merge_file(self, state: 'ModuleState', args: T.List['TYPE_var'], kwargs: 'MergeFile') -> ModuleReturnValue:
- if not shutil.which('xgettext'):
+ if self.tools['msgfmt'] is None:
+ self.tools['msgfmt'] = state.find_program('msgfmt', required=False, for_machine=mesonlib.MachineChoice.BUILD)
+ if not self.tools['msgfmt'].found():
self.nogettext_warning()
return ModuleReturnValue(None, [])
podir = path.join(state.build_to_src, state.subdir, kwargs['po_dir'])
@@ -175,6 +180,7 @@ class I18nModule(ExtensionModule):
command.extend(state.environment.get_build_command())
command.extend([
'--internal', 'msgfmthelper',
+ '--msgfmt=' + self.tools['msgfmt'].get_path(),
])
if datadirs:
command.append(datadirs)
@@ -218,9 +224,13 @@ class I18nModule(ExtensionModule):
),
)
def gettext(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'Gettext') -> ModuleReturnValue:
- if not shutil.which('xgettext'):
- self.nogettext_warning()
- return ModuleReturnValue(None, [])
+ for tool in ['msgfmt', 'msginit', 'msgmerge', 'xgettext']:
+ if self.tools[tool] is None:
+ self.tools[tool] = state.find_program(tool, required=False, for_machine=mesonlib.MachineChoice.BUILD)
+ # still not found?
+ if not self.tools[tool].found():
+ self.nogettext_warning()
+ return ModuleReturnValue(None, [])
packagename = args[0]
pkg_arg = f'--pkgname={packagename}'
@@ -246,6 +256,7 @@ class I18nModule(ExtensionModule):
potargs.append(datadirs)
if extra_arg:
potargs.append(extra_arg)
+ potargs.append('--xgettext=' + self.tools['xgettext'].get_path())
pottarget = build.RunTarget(packagename + '-pot', potargs, [], state.subdir, state.subproject)
targets.append(pottarget)
@@ -261,7 +272,7 @@ class I18nModule(ExtensionModule):
f'{packagename}-{l}.mo',
path.join(state.subdir, l, 'LC_MESSAGES'),
state.subproject,
- ['msgfmt', '@INPUT@', '-o', '@OUTPUT@'],
+ [self.tools['msgfmt'], '@INPUT@', '-o', '@OUTPUT@'],
[po_file],
[f'{packagename}.mo'],
install=install,
@@ -285,6 +296,8 @@ class I18nModule(ExtensionModule):
updatepoargs.append(datadirs)
if extra_arg:
updatepoargs.append(extra_arg)
+ for tool in ['msginit', 'msgmerge']:
+ updatepoargs.append(f'--{tool}=' + self.tools[tool].get_path())
updatepotarget = build.RunTarget(packagename + '-update-po', updatepoargs, [], state.subdir, state.subproject)
targets.append(updatepotarget)
@@ -305,8 +318,8 @@ class I18nModule(ExtensionModule):
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()
+ if self.tools['itstool'] is None:
+ self.tools['itstool'] = state.find_program('itstool', for_machine=mesonlib.MachineChoice.BUILD)
mo_targets = kwargs['mo_targets']
its_files = kwargs.get('its_files', [])
@@ -320,7 +333,8 @@ class I18nModule(ExtensionModule):
command.extend([
'--internal', 'itstool', 'join',
'-i', '@INPUT@',
- '-o', '@OUTPUT@'
+ '-o', '@OUTPUT@',
+ '--itstool=' + self.tools['itstool'].get_path(),
])
if its_files:
for fname in its_files: