Fix consistency in variables kwarg
Share common code to extract the `variables` kwarg in declare_dependency() and pkg.generate().
This commit is contained in:
parent
2e80c52129
commit
bcf369ea3c
|
@ -49,7 +49,8 @@ keyword arguments.
|
|||
generated file. The strings must be in the form `name=value` and may
|
||||
reference other pkgconfig variables,
|
||||
e.g. `datadir=${prefix}/share`. The names `prefix`, `libdir` and
|
||||
`includedir` are reserved and may not be used.
|
||||
`includedir` are reserved and may not be used. *Since 0.56.0* it can also be a
|
||||
dictionary.
|
||||
- `version` a string describing the version of this library, used to set the
|
||||
`Version:` field. (*since 0.46.0*) Defaults to the project version if unspecified.
|
||||
- `d_module_versions` a list of module version flags used when compiling
|
||||
|
|
|
@ -427,7 +427,7 @@ keyword arguments:
|
|||
- `version`: the version of this dependency, such as `1.2.3`
|
||||
- `variables` *(since 0.54.0)*: a dictionary of arbitrary strings, this is meant to be used
|
||||
in subprojects where special variables would be provided via cmake or
|
||||
pkg-config.
|
||||
pkg-config. *since 0.56.0* it can also be a list of `'key=value'` strings.
|
||||
|
||||
### dependency()
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
## Consistency between `declare_dependency()` and `pkgconfig.generate()` variables
|
||||
|
||||
The `variables` keyword argument in `declare_dependency()` used to only support
|
||||
dictionary and `pkgconfig.generate()` only list of strings. They now both support
|
||||
dictionary and list of strings in the format `'name=value'`. This makes easier
|
||||
to share a common set of variables for both:
|
||||
|
||||
```meson
|
||||
vars = {'foo': 'bar'}
|
||||
dep = declare_dependency(..., variables: vars)
|
||||
pkg.generate(..., variables: vars)
|
||||
```
|
|
@ -2680,6 +2680,32 @@ class Interpreter(InterpreterBase):
|
|||
def func_files(self, node, args, kwargs):
|
||||
return [mesonlib.File.from_source_file(self.environment.source_dir, self.subdir, fname) for fname in args]
|
||||
|
||||
# Used by declare_dependency() and pkgconfig.generate()
|
||||
def extract_variables(self, kwargs, argname='variables', list_new=False, dict_new=False):
|
||||
variables = kwargs.get(argname, {})
|
||||
if isinstance(variables, dict):
|
||||
if dict_new and variables:
|
||||
FeatureNew.single_use('variables as dictionary', '0.56.0', self.subproject)
|
||||
else:
|
||||
varlist = mesonlib.stringlistify(variables)
|
||||
if list_new:
|
||||
FeatureNew.single_use('variables as list of strings', '0.56.0', self.subproject)
|
||||
variables = {}
|
||||
for v in varlist:
|
||||
try:
|
||||
(key, value) = v.split('=', 1)
|
||||
except ValueError:
|
||||
raise InterpreterException('Variable {!r} must have a value separated by equals sign.'.format(v))
|
||||
variables[key.strip()] = value.strip()
|
||||
for k, v in variables.items():
|
||||
if not k or not v:
|
||||
raise InterpreterException('Empty variable name or value')
|
||||
if any(c.isspace() for c in k):
|
||||
raise InterpreterException('Invalid whitespace in variable name "{}"'.format(k))
|
||||
if not isinstance(v, str):
|
||||
raise InterpreterException('variables values must be strings.')
|
||||
return variables
|
||||
|
||||
@FeatureNewKwargs('declare_dependency', '0.46.0', ['link_whole'])
|
||||
@FeatureNewKwargs('declare_dependency', '0.54.0', ['variables'])
|
||||
@permittedKwargs(permitted_kwargs['declare_dependency'])
|
||||
|
@ -2696,12 +2722,7 @@ class Interpreter(InterpreterBase):
|
|||
deps = unholder(extract_as_list(kwargs, 'dependencies'))
|
||||
compile_args = mesonlib.stringlistify(kwargs.get('compile_args', []))
|
||||
link_args = mesonlib.stringlistify(kwargs.get('link_args', []))
|
||||
variables = kwargs.get('variables', {})
|
||||
if not isinstance(variables, dict):
|
||||
raise InterpreterException('variables must be a dict.')
|
||||
if not all(isinstance(v, str) for v in variables.values()):
|
||||
# Because that is how they will come from pkg-config and cmake
|
||||
raise InterpreterException('variables values be strings.')
|
||||
variables = self.extract_variables(kwargs, list_new=True)
|
||||
final_deps = []
|
||||
for d in deps:
|
||||
try:
|
||||
|
|
|
@ -513,31 +513,17 @@ class PkgConfigModule(ExtensionModule):
|
|||
|
||||
deps.remove_dups()
|
||||
|
||||
def parse_variable_list(stringlist):
|
||||
def parse_variable_list(vardict):
|
||||
reserved = ['prefix', 'libdir', 'includedir']
|
||||
variables = []
|
||||
for var in stringlist:
|
||||
# foo=bar=baz is ('foo', 'bar=baz')
|
||||
l = var.split('=', 1)
|
||||
if len(l) < 2:
|
||||
raise mesonlib.MesonException('Invalid variable "{}". Variables must be in \'name=value\' format'.format(var))
|
||||
|
||||
name, value = l[0].strip(), l[1].strip()
|
||||
if not name or not value:
|
||||
raise mesonlib.MesonException('Invalid variable "{}". Variables must be in \'name=value\' format'.format(var))
|
||||
|
||||
# Variable names must not contain whitespaces
|
||||
if any(c.isspace() for c in name):
|
||||
raise mesonlib.MesonException('Invalid whitespace in assignment "{}"'.format(var))
|
||||
|
||||
for name, value in vardict.items():
|
||||
if name in reserved:
|
||||
raise mesonlib.MesonException('Variable "{}" is reserved'.format(name))
|
||||
|
||||
variables.append((name, value))
|
||||
|
||||
return variables
|
||||
|
||||
variables = parse_variable_list(mesonlib.stringlistify(kwargs.get('variables', [])))
|
||||
variables = self.interpreter.extract_variables(kwargs, dict_new=True)
|
||||
variables = parse_variable_list(variables)
|
||||
|
||||
pcfile = filebase + '.pc'
|
||||
pkgroot = kwargs.get('install_dir', default_install_dir)
|
||||
|
@ -552,7 +538,9 @@ class PkgConfigModule(ExtensionModule):
|
|||
version, pcfile, conflicts, variables,
|
||||
False, dataonly)
|
||||
res = build.Data(mesonlib.File(True, state.environment.get_scratch_dir(), pcfile), pkgroot)
|
||||
variables = parse_variable_list(mesonlib.stringlistify(kwargs.get('uninstalled_variables', [])))
|
||||
variables = self.interpreter.extract_variables(kwargs, argname='uninstalled_variables', dict_new=True)
|
||||
variables = parse_variable_list(variables)
|
||||
|
||||
pcfile = filebase + '-uninstalled.pc'
|
||||
self.generate_pkgconfig_file(state, deps, subdirs, name, description, url,
|
||||
version, pcfile, conflicts, variables,
|
||||
|
|
|
@ -6040,6 +6040,7 @@ class LinuxlikeTests(BasePlatformTests):
|
|||
self.assertTrue(libhello_nolib.found())
|
||||
self.assertEqual(libhello_nolib.get_link_args(), [])
|
||||
self.assertEqual(libhello_nolib.get_compile_args(), [])
|
||||
self.assertEqual(libhello_nolib.get_pkgconfig_variable('foo', {}), 'bar')
|
||||
|
||||
def test_pkgconfig_gen_deps(self):
|
||||
'''
|
||||
|
|
|
@ -59,3 +59,6 @@ idep = declare_dependency()
|
|||
assert(idep.get_variable(pkgconfig : 'foo', cmake : 'foo', configtool : 'foo',
|
||||
default_value : default) == default,
|
||||
'something went wrong with an InternalDependency with no variables.')
|
||||
|
||||
idep = declare_dependency(variables : ['foo=value'])
|
||||
assert(idep.get_variable(internal: 'foo') == 'value')
|
||||
|
|
|
@ -64,7 +64,8 @@ pkgg.generate(
|
|||
name : 'libhello_nolib',
|
||||
description : 'A minimalistic pkgconfig file.',
|
||||
version : libver,
|
||||
dataonly: true
|
||||
dataonly: true,
|
||||
variables : {'foo': 'bar'},
|
||||
)
|
||||
|
||||
# Regression test for 2 cases:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"stdout": [
|
||||
{
|
||||
"line": "test cases/failing/47 pkgconfig variables zero length/meson.build:8:5: ERROR: Invalid variable \"=value\". Variables must be in 'name=value' format"
|
||||
"line": "test cases/failing/47 pkgconfig variables zero length/meson.build:8:5: ERROR: Empty variable name or value"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"stdout": [
|
||||
{
|
||||
"line": "test cases/failing/48 pkgconfig variables zero length value/meson.build:8:5: ERROR: Invalid variable \"key=\". Variables must be in 'name=value' format"
|
||||
"line": "test cases/failing/48 pkgconfig variables zero length value/meson.build:8:5: ERROR: Empty variable name or value"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"stdout": [
|
||||
{
|
||||
"line": "test cases/failing/49 pkgconfig variables not key value/meson.build:8:5: ERROR: Invalid variable \"this_should_be_key_value\". Variables must be in 'name=value' format"
|
||||
"line": "test cases/failing/49 pkgconfig variables not key value/meson.build:8:5: ERROR: Variable 'this_should_be_key_value' must have a value separated by equals sign."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue