intl custom dependency

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
pull/8888/head
Eli Schwartz 4 years ago
parent ad206037e3
commit 2c6ccfe4c4
No known key found for this signature in database
GPG Key ID: CEB167EFB5722BD6
  1. 21
      docs/markdown/Dependencies.md
  2. 35
      docs/markdown/snippets/intl-dependency.md
  3. 3
      mesonbuild/dependencies/__init__.py
  4. 28
      mesonbuild/dependencies/misc.py

@ -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 You can use the keyword `method` to let Meson know what method to use
when searching for the dependency. The default value is `auto`. when searching for the dependency. The default value is `auto`.
Additional dependencies methods are `pkg-config`, `config-tool`, `cmake`, Additional dependencies methods are `pkg-config`, `config-tool`, `cmake`,
`system`, `sysconfig`, `qmake`, `extraframework` and `dub`. `builtin`, `system`, `sysconfig`, `qmake`, `extraframework` and `dub`.
```meson ```meson
cups_dep = dependency('cups', method : 'pkg-config') cups_dep = dependency('cups', method : 'pkg-config')
@ -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 putting these in meson upstream the barrier of using them is lowered, as
projects using meson don't have to re-implement the logic. 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 ## Blocks
@ -400,6 +409,16 @@ language.
*New in 0.56.0* the dependencies now return proper dependency types *New in 0.56.0* the dependencies now return proper dependency types
and `get_variable` and similar methods should work as expected. 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 ## libwmf
*(added 0.44.0)* *(added 0.44.0)*

@ -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
```

@ -35,7 +35,7 @@ from .scalapack import scalapack_factory
from .misc import ( from .misc import (
BlocksDependency, OpenMPDependency, cups_factory, curses_factory, gpgme_factory, BlocksDependency, OpenMPDependency, cups_factory, curses_factory, gpgme_factory,
libgcrypt_factory, libwmf_factory, netcdf_factory, pcap_factory, python3_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 .platform import AppleFrameworks
from .qt import qt4_factory, qt5_factory, qt6_factory from .qt import qt4_factory, qt5_factory, qt6_factory
@ -252,6 +252,7 @@ packages.update({
'libgcrypt': libgcrypt_factory, 'libgcrypt': libgcrypt_factory,
'gpgme': gpgme_factory, 'gpgme': gpgme_factory,
'shaderc': shaderc_factory, 'shaderc': shaderc_factory,
'intl': intl_factory,
# From platform: # From platform:
'appleframeworks': AppleFrameworks, 'appleframeworks': AppleFrameworks,

@ -24,7 +24,7 @@ from .. import mesonlib
from .. import mlog from .. import mlog
from ..environment import detect_cpu_family from ..environment import detect_cpu_family
from .base import DependencyException, DependencyMethods from .base import DependencyException, DependencyMethods
from .base import SystemDependency from .base import BuiltinDependency, SystemDependency
from .cmake import CMakeDependency from .cmake import CMakeDependency
from .configtool import ConfigToolDependency from .configtool import ConfigToolDependency
from .factory import DependencyFactory, factory_methods from .factory import DependencyFactory, factory_methods
@ -487,6 +487,25 @@ class CursesSystemDependency(SystemDependency):
return [DependencyMethods.SYSTEM] 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}) @factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.SYSTEM})
def curses_factory(env: 'Environment', def curses_factory(env: 'Environment',
for_machine: 'MachineChoice', for_machine: 'MachineChoice',
@ -596,3 +615,10 @@ threads_factory = DependencyFactory(
cmake_name='Threads', cmake_name='Threads',
system_class=ThreadDependency, system_class=ThreadDependency,
) )
intl_factory = DependencyFactory(
'intl',
[DependencyMethods.BUILTIN, DependencyMethods.SYSTEM],
builtin_class=IntlBuiltinDependency,
system_class=IntlSystemDependency,
)

Loading…
Cancel
Save