Skip to content

Commit

Permalink
intl custom dependency
Browse files Browse the repository at this point in the history
Checking how to aquire the *gettext family of symbols portably is
annoyingly complex, and may come from the libc, or standalone.

builtin dependency:

    This detects if libintl is unneeded, because the *gettext family of
    symbols is available in the libc.

system dependency:

    This detects if libintl is installed as separate software, linkable via
    -lintl; unfortunately, GNU gettext does not ship pkg-config files for
    it.

Fixes #3929
  • Loading branch information
eli-schwartz committed Jun 17, 2021
1 parent ad20603 commit 2c6ccfe
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 3 deletions.
21 changes: 20 additions & 1 deletion docs/markdown/Dependencies.md
Expand Up @@ -141,7 +141,7 @@ of all the work behind the scenes to make this work.
You can use the keyword `method` to let Meson know what method to use
when searching for the dependency. The default value is `auto`.
Additional dependencies methods are `pkg-config`, `config-tool`, `cmake`,
`system`, `sysconfig`, `qmake`, `extraframework` and `dub`.
`builtin`, `system`, `sysconfig`, `qmake`, `extraframework` and `dub`.

```meson
cups_dep = dependency('cups', method : 'pkg-config')
Expand Down Expand Up @@ -282,6 +282,15 @@ in the build system DSL or with a script, likely calling
putting these in meson upstream the barrier of using them is lowered, as
projects using meson don't have to re-implement the logic.

## Builtin

Some dependencies provide no valid methods for discovery on some systems,
because they are provided internally by the language. One example of this is
intl, which is built into GNU or musl libc but otherwise comes as a `system`
dependency.

In these cases meson provides convenience wrappers for the `system` dependency,
but first checks if the functionality is usable by default.

## Blocks

Expand Down Expand Up @@ -400,6 +409,16 @@ language.
*New in 0.56.0* the dependencies now return proper dependency types
and `get_variable` and similar methods should work as expected.

## intl

*(added 0.59.0)*

Provides access to the `*gettext` family of C functions. On systems where this
is not built into libc, tries to find an external library providing them
instead.

`method` may be `auto`, `builtin` or `system`.

## libwmf

*(added 0.44.0)*
Expand Down
35 changes: 35 additions & 0 deletions docs/markdown/snippets/intl-dependency.md
@@ -0,0 +1,35 @@
## New custom dependency for libintl

Meson can now find the library needed for translating messages via gettext.
This works both on systems where libc provides gettext, such as GNU or musl,
and on systems where the gettext project's standalone intl support library is
required, such as macOS.

Rather than doing something such as:

```
intl_dep = dependency('', required: false)
if cc.has_function('ngettext')
intl_found = true
else
intl_dep = cc.find_library('intl', required: false)
intl_found = intl_dep.found()
endif
if intl_found
# build options that need gettext
conf.set('ENABLE_NLS', 1)
endif
```

one may simply use:

```
intl_dep = dependency('intl')
if intl_dep.found()
# build options that need gettext
conf.set('ENABLE_NLS', 1)
endif
```
3 changes: 2 additions & 1 deletion mesonbuild/dependencies/__init__.py
Expand Up @@ -35,7 +35,7 @@
from .misc import (
BlocksDependency, OpenMPDependency, cups_factory, curses_factory, gpgme_factory,
libgcrypt_factory, libwmf_factory, netcdf_factory, pcap_factory, python3_factory,
shaderc_factory, threads_factory, ThreadDependency,
shaderc_factory, threads_factory, ThreadDependency, intl_factory,
)
from .platform import AppleFrameworks
from .qt import qt4_factory, qt5_factory, qt6_factory
Expand Down Expand Up @@ -252,6 +252,7 @@ def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.
'libgcrypt': libgcrypt_factory,
'gpgme': gpgme_factory,
'shaderc': shaderc_factory,
'intl': intl_factory,

# From platform:
'appleframeworks': AppleFrameworks,
Expand Down
28 changes: 27 additions & 1 deletion mesonbuild/dependencies/misc.py
Expand Up @@ -24,7 +24,7 @@
from .. import mlog
from ..environment import detect_cpu_family
from .base import DependencyException, DependencyMethods
from .base import SystemDependency
from .base import BuiltinDependency, SystemDependency
from .cmake import CMakeDependency
from .configtool import ConfigToolDependency
from .factory import DependencyFactory, factory_methods
Expand Down Expand Up @@ -487,6 +487,25 @@ def get_methods() -> T.List[DependencyMethods]:
return [DependencyMethods.SYSTEM]


class IntlBuiltinDependency(BuiltinDependency):
def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
super().__init__(name, env, kwargs)

if self.clib_compiler.has_function('ngettext', '', env)[0]:
self.is_found = True


class IntlSystemDependency(SystemDependency):
def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
super().__init__(name, env, kwargs)

h = self.clib_compiler.has_header('libintl.h', '', env)
self.link_args = self.clib_compiler.find_library('intl', env, [])

if h and self.link_args:
self.is_found = True


@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.SYSTEM})
def curses_factory(env: 'Environment',
for_machine: 'MachineChoice',
Expand Down Expand Up @@ -596,3 +615,10 @@ def shaderc_factory(env: 'Environment',
cmake_name='Threads',
system_class=ThreadDependency,
)

intl_factory = DependencyFactory(
'intl',
[DependencyMethods.BUILTIN, DependencyMethods.SYSTEM],
builtin_class=IntlBuiltinDependency,
system_class=IntlSystemDependency,
)

0 comments on commit 2c6ccfe

Please sign in to comment.