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
|
generated file. The strings must be in the form `name=value` and may
|
||||||
reference other pkgconfig variables,
|
reference other pkgconfig variables,
|
||||||
e.g. `datadir=${prefix}/share`. The names `prefix`, `libdir` and
|
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` 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.
|
`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
|
- `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`
|
- `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
|
- `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
|
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()
|
### 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):
|
def func_files(self, node, args, kwargs):
|
||||||
return [mesonlib.File.from_source_file(self.environment.source_dir, self.subdir, fname) for fname in args]
|
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.46.0', ['link_whole'])
|
||||||
@FeatureNewKwargs('declare_dependency', '0.54.0', ['variables'])
|
@FeatureNewKwargs('declare_dependency', '0.54.0', ['variables'])
|
||||||
@permittedKwargs(permitted_kwargs['declare_dependency'])
|
@permittedKwargs(permitted_kwargs['declare_dependency'])
|
||||||
|
@ -2696,12 +2722,7 @@ class Interpreter(InterpreterBase):
|
||||||
deps = unholder(extract_as_list(kwargs, 'dependencies'))
|
deps = unholder(extract_as_list(kwargs, 'dependencies'))
|
||||||
compile_args = mesonlib.stringlistify(kwargs.get('compile_args', []))
|
compile_args = mesonlib.stringlistify(kwargs.get('compile_args', []))
|
||||||
link_args = mesonlib.stringlistify(kwargs.get('link_args', []))
|
link_args = mesonlib.stringlistify(kwargs.get('link_args', []))
|
||||||
variables = kwargs.get('variables', {})
|
variables = self.extract_variables(kwargs, list_new=True)
|
||||||
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.')
|
|
||||||
final_deps = []
|
final_deps = []
|
||||||
for d in deps:
|
for d in deps:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -513,31 +513,17 @@ class PkgConfigModule(ExtensionModule):
|
||||||
|
|
||||||
deps.remove_dups()
|
deps.remove_dups()
|
||||||
|
|
||||||
def parse_variable_list(stringlist):
|
def parse_variable_list(vardict):
|
||||||
reserved = ['prefix', 'libdir', 'includedir']
|
reserved = ['prefix', 'libdir', 'includedir']
|
||||||
variables = []
|
variables = []
|
||||||
for var in stringlist:
|
for name, value in vardict.items():
|
||||||
# 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))
|
|
||||||
|
|
||||||
if name in reserved:
|
if name in reserved:
|
||||||
raise mesonlib.MesonException('Variable "{}" is reserved'.format(name))
|
raise mesonlib.MesonException('Variable "{}" is reserved'.format(name))
|
||||||
|
|
||||||
variables.append((name, value))
|
variables.append((name, value))
|
||||||
|
|
||||||
return variables
|
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'
|
pcfile = filebase + '.pc'
|
||||||
pkgroot = kwargs.get('install_dir', default_install_dir)
|
pkgroot = kwargs.get('install_dir', default_install_dir)
|
||||||
|
@ -552,7 +538,9 @@ class PkgConfigModule(ExtensionModule):
|
||||||
version, pcfile, conflicts, variables,
|
version, pcfile, conflicts, variables,
|
||||||
False, dataonly)
|
False, dataonly)
|
||||||
res = build.Data(mesonlib.File(True, state.environment.get_scratch_dir(), pcfile), pkgroot)
|
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'
|
pcfile = filebase + '-uninstalled.pc'
|
||||||
self.generate_pkgconfig_file(state, deps, subdirs, name, description, url,
|
self.generate_pkgconfig_file(state, deps, subdirs, name, description, url,
|
||||||
version, pcfile, conflicts, variables,
|
version, pcfile, conflicts, variables,
|
||||||
|
|
|
@ -6040,6 +6040,7 @@ class LinuxlikeTests(BasePlatformTests):
|
||||||
self.assertTrue(libhello_nolib.found())
|
self.assertTrue(libhello_nolib.found())
|
||||||
self.assertEqual(libhello_nolib.get_link_args(), [])
|
self.assertEqual(libhello_nolib.get_link_args(), [])
|
||||||
self.assertEqual(libhello_nolib.get_compile_args(), [])
|
self.assertEqual(libhello_nolib.get_compile_args(), [])
|
||||||
|
self.assertEqual(libhello_nolib.get_pkgconfig_variable('foo', {}), 'bar')
|
||||||
|
|
||||||
def test_pkgconfig_gen_deps(self):
|
def test_pkgconfig_gen_deps(self):
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -59,3 +59,6 @@ idep = declare_dependency()
|
||||||
assert(idep.get_variable(pkgconfig : 'foo', cmake : 'foo', configtool : 'foo',
|
assert(idep.get_variable(pkgconfig : 'foo', cmake : 'foo', configtool : 'foo',
|
||||||
default_value : default) == default,
|
default_value : default) == default,
|
||||||
'something went wrong with an InternalDependency with no variables.')
|
'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',
|
name : 'libhello_nolib',
|
||||||
description : 'A minimalistic pkgconfig file.',
|
description : 'A minimalistic pkgconfig file.',
|
||||||
version : libver,
|
version : libver,
|
||||||
dataonly: true
|
dataonly: true,
|
||||||
|
variables : {'foo': 'bar'},
|
||||||
)
|
)
|
||||||
|
|
||||||
# Regression test for 2 cases:
|
# Regression test for 2 cases:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"stdout": [
|
"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": [
|
"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": [
|
"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