aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Schwartz <eschwartz@archlinux.org>2021-08-08 01:11:50 -0400
committerEli Schwartz <eschwartz@archlinux.org>2021-08-09 18:25:17 -0400
commit487d45c1e5bfff0fbdb4747841db6a0b5b124af9 (patch)
treeb039f3d6ab61277040e39a43a9fd8d81de070189
parent27b319526c5114a63c63f00c46c4696722e71f56 (diff)
downloadmeson-487d45c1e5bfff0fbdb4747841db6a0b5b124af9.zip
meson-487d45c1e5bfff0fbdb4747841db6a0b5b124af9.tar.gz
meson-487d45c1e5bfff0fbdb4747841db6a0b5b124af9.tar.bz2
i18n: use real build/install targets for gmo files
Don't just create a .PHONY target which runs a script that magically generates files ninja doesn't know about. It results in untracked files, and `meson install` has to run additional commands instead of copying over files, and then cannot track them to uninstall them later. I'm not even really sure why it was originally done via a proxy script, most likely bad legacy design. This is after all one of the oldest modules... One side effect of this is that meson doesn't know how to rename build.CustomTarget files on install (only data files are supported?), and every file needs to be installed as "domainname.mo" so it must be named that in-tree too. To prevent clashes, every locale gets its own locale-specific subdirectory. Once we are doing that anyway, we can output them to the actual structure required by the gettext family of functions, and bindtextdomain() can therefore point to this location if desired. This might be useful for running localized programs from the build tree.
-rw-r--r--mesonbuild/modules/i18n.py42
-rw-r--r--mesonbuild/scripts/gettext.py32
2 files changed, 23 insertions, 51 deletions
diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py
index f10fdbe..6e841d0 100644
--- a/mesonbuild/modules/i18n.py
+++ b/mesonbuild/modules/i18n.py
@@ -17,6 +17,7 @@ import shutil
from os import path
from .. import coredata, mesonlib, build, mlog
from ..mesonlib import MesonException
+from ..scripts.gettext import read_linguas
from . import ModuleReturnValue
from . import ExtensionModule
from ..interpreterbase import permittedKwargs, FeatureNew, FeatureNewKwargs
@@ -141,6 +142,7 @@ class I18nModule(ExtensionModule):
languages = mesonlib.stringlistify(kwargs.get('languages', []))
datadirs = self._get_data_dirs(state, mesonlib.stringlistify(kwargs.get('data_dirs', [])))
extra_args = mesonlib.stringlistify(kwargs.get('args', []))
+ targets = []
preset = kwargs.pop('preset', None)
if preset:
@@ -161,11 +163,27 @@ class I18nModule(ExtensionModule):
if extra_args:
potargs.append(extra_args)
pottarget = build.RunTarget(packagename + '-pot', potargs, [], state.subdir, state.subproject)
+ targets.append(pottarget)
- gmoargs = state.environment.get_build_command() + ['--internal', 'gettext', 'gen_gmo']
- if lang_arg:
- gmoargs.append(lang_arg)
- gmotarget = build.RunTarget(packagename + '-gmo', gmoargs, [], state.subdir, state.subproject)
+ install = kwargs.get('install', True)
+ install_dir = kwargs.get('install_dir', state.environment.coredata.get_option(mesonlib.OptionKey('localedir')))
+ if not languages:
+ languages = read_linguas(path.join(state.environment.source_dir, state.subdir))
+ for l in languages:
+ po_file = mesonlib.File.from_source_file(state.environment.source_dir,
+ state.subdir, l+'.po')
+ gmo_kwargs = {'command': ['msgfmt', '@INPUT@', '-o', '@OUTPUT@'],
+ 'input': po_file,
+ 'output': packagename+'.mo',
+ 'install': install,
+ # We have multiple files all installed as packagename+'.mo' in different install subdirs.
+ # What we really wanted to do, probably, is have a rename: kwarg, but that's not available
+ # to custom_targets. Crude hack: set the build target's subdir manually.
+ # Bonus: the build tree has something usable as an uninstalled bindtextdomain() target dir.
+ 'install_dir': path.join(install_dir, l, 'LC_MESSAGES'),
+ }
+ gmotarget = build.CustomTarget(l+'.mo', path.join(state.subdir, l, 'LC_MESSAGES'), state.subproject, gmo_kwargs)
+ targets.append(gmotarget)
updatepoargs = state.environment.get_build_command() + ['--internal', 'gettext', 'update_po', pkg_arg]
if lang_arg:
@@ -175,21 +193,7 @@ class I18nModule(ExtensionModule):
if extra_args:
updatepoargs.append(extra_args)
updatepotarget = build.RunTarget(packagename + '-update-po', updatepoargs, [], state.subdir, state.subproject)
-
- targets = [pottarget, gmotarget, updatepotarget]
-
- install = kwargs.get('install', True)
- if install:
- install_dir = kwargs.get('install_dir', state.environment.coredata.get_option(mesonlib.OptionKey('localedir')))
- script = state.environment.get_build_command()
- args = ['--internal', 'gettext', 'install',
- '--subdir=' + state.subdir,
- '--localedir=' + install_dir,
- pkg_arg]
- if lang_arg:
- args.append(lang_arg)
- iscript = state.backend.get_executable_serialisation(script + args)
- targets.append(iscript)
+ targets.append(updatepotarget)
return ModuleReturnValue(None, targets)
diff --git a/mesonbuild/scripts/gettext.py b/mesonbuild/scripts/gettext.py
index b1ce6af..d6bd366 100644
--- a/mesonbuild/scripts/gettext.py
+++ b/mesonbuild/scripts/gettext.py
@@ -13,10 +13,8 @@
# limitations under the License.
import os
-import shutil
import argparse
import subprocess
-from . import destdir_join
import typing as T
parser = argparse.ArgumentParser()
@@ -61,12 +59,6 @@ def run_potgen(src_sub: str, pkgname: str, datadirs: str, args: T.List[str]) ->
'-D', os.environ['MESON_SOURCE_ROOT'], '-k_', '-o', ofile] + args,
env=child_env)
-def gen_gmo(src_sub: str, bld_sub: str, langs: T.List[str]) -> int:
- for l in langs:
- subprocess.check_call(['msgfmt', os.path.join(src_sub, l + '.po'),
- '-o', os.path.join(bld_sub, l + '.gmo')])
- return 0
-
def update_po(src_sub: str, pkgname: str, langs: T.List[str]) -> int:
potfile = os.path.join(src_sub, pkgname + '.pot')
for l in langs:
@@ -77,19 +69,6 @@ def update_po(src_sub: str, pkgname: str, langs: T.List[str]) -> int:
subprocess.check_call(['msginit', '--input', potfile, '--output-file', pofile, '--locale', l, '--no-translator'])
return 0
-def do_install(src_sub: str, bld_sub: str, dest: str, pkgname: str, langs: T.List[str]) -> int:
- for l in langs:
- srcfile = os.path.join(bld_sub, l + '.gmo')
- outfile = os.path.join(dest, l, 'LC_MESSAGES',
- pkgname + '.mo')
- tempfile = outfile + '.tmp'
- os.makedirs(os.path.dirname(outfile), exist_ok=True)
- shutil.copy2(srcfile, tempfile)
- os.replace(tempfile, outfile)
- if not os.getenv('MESON_INSTALL_QUIET', False):
- print(f'Installing {srcfile} to {outfile}')
- return 0
-
def run(args: T.List[str]) -> int:
options = parser.parse_args(args)
subcmd = options.command
@@ -99,27 +78,16 @@ def run(args: T.List[str]) -> int:
if options.subdir:
subdir = options.subdir
src_sub = os.path.join(os.environ['MESON_SOURCE_ROOT'], subdir)
- bld_sub = os.path.join(os.environ['MESON_BUILD_ROOT'], subdir)
if not langs:
langs = read_linguas(src_sub)
if subcmd == 'pot':
return run_potgen(src_sub, options.pkgname, options.datadirs, extra_args)
- elif subcmd == 'gen_gmo':
- return gen_gmo(src_sub, bld_sub, langs)
elif subcmd == 'update_po':
if run_potgen(src_sub, options.pkgname, options.datadirs, extra_args) != 0:
return 1
return update_po(src_sub, options.pkgname, langs)
- elif subcmd == 'install':
- destdir = os.environ.get('DESTDIR', '')
- dest = destdir_join(destdir, os.path.join(os.environ['MESON_INSTALL_PREFIX'],
- options.localedir))
- if gen_gmo(src_sub, bld_sub, langs) != 0:
- return 1
- do_install(src_sub, bld_sub, dest, options.pkgname, langs)
else:
print('Unknown subcommand.')
return 1
- return 0