summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2020-10-15 09:56:08 -0400
committerJussi Pakkanen <jpakkane@gmail.com>2020-10-16 18:09:56 +0300
commitbcf369ea3c6ac9d48759a9a11304a853dfdab5ff (patch)
tree3e5080da666144231c1c36ceaeb62fb3727df07a
parent2e80c521295f45105229e5c7bffa3ebfd60b3445 (diff)
downloadmeson-bcf369ea3c6ac9d48759a9a11304a853dfdab5ff.tar.gz
Fix consistency in variables kwarg
Share common code to extract the `variables` kwarg in declare_dependency() and pkg.generate().
-rw-r--r--docs/markdown/Pkgconfig-module.md3
-rw-r--r--docs/markdown/Reference-manual.md2
-rw-r--r--docs/markdown/snippets/pkg_idep_variables.md12
-rw-r--r--mesonbuild/interpreter.py33
-rw-r--r--mesonbuild/modules/pkgconfig.py26
-rwxr-xr-xrun_unittests.py1
-rw-r--r--test cases/common/218 dependency get_variable method/meson.build3
-rw-r--r--test cases/common/47 pkgconfig-gen/meson.build3
-rw-r--r--test cases/failing/47 pkgconfig variables zero length/test.json2
-rw-r--r--test cases/failing/48 pkgconfig variables zero length value/test.json2
-rw-r--r--test cases/failing/49 pkgconfig variables not key value/test.json2
11 files changed, 58 insertions, 31 deletions
diff --git a/docs/markdown/Pkgconfig-module.md b/docs/markdown/Pkgconfig-module.md
index 7b68e2408..e9aa4a226 100644
--- a/docs/markdown/Pkgconfig-module.md
+++ b/docs/markdown/Pkgconfig-module.md
@@ -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
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 38ae5582b..13111d1cc 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -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()
diff --git a/docs/markdown/snippets/pkg_idep_variables.md b/docs/markdown/snippets/pkg_idep_variables.md
new file mode 100644
index 000000000..4e69b18e3
--- /dev/null
+++ b/docs/markdown/snippets/pkg_idep_variables.md
@@ -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)
+```
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index ad6f04eb7..cd201d097 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -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:
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
index 912c9ff9b..38c96a9ca 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -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,
diff --git a/run_unittests.py b/run_unittests.py
index 708dcb70a..539ecd31b 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -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):
'''
diff --git a/test cases/common/218 dependency get_variable method/meson.build b/test cases/common/218 dependency get_variable method/meson.build
index 8c189bbe3..9f60836e2 100644
--- a/test cases/common/218 dependency get_variable method/meson.build
+++ b/test cases/common/218 dependency get_variable method/meson.build
@@ -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')
diff --git a/test cases/common/47 pkgconfig-gen/meson.build b/test cases/common/47 pkgconfig-gen/meson.build
index 8c16cd5bc..4638123cf 100644
--- a/test cases/common/47 pkgconfig-gen/meson.build
+++ b/test cases/common/47 pkgconfig-gen/meson.build
@@ -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:
diff --git a/test cases/failing/47 pkgconfig variables zero length/test.json b/test cases/failing/47 pkgconfig variables zero length/test.json
index 097fee12e..39ffde4c6 100644
--- a/test cases/failing/47 pkgconfig variables zero length/test.json
+++ b/test cases/failing/47 pkgconfig variables zero length/test.json
@@ -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"
}
]
}
diff --git a/test cases/failing/48 pkgconfig variables zero length value/test.json b/test cases/failing/48 pkgconfig variables zero length value/test.json
index 50a35ce97..8aa1bc58f 100644
--- a/test cases/failing/48 pkgconfig variables zero length value/test.json
+++ b/test cases/failing/48 pkgconfig variables zero length value/test.json
@@ -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"
}
]
}
diff --git a/test cases/failing/49 pkgconfig variables not key value/test.json b/test cases/failing/49 pkgconfig variables not key value/test.json
index cf07e6221..082bd7955 100644
--- a/test cases/failing/49 pkgconfig variables not key value/test.json
+++ b/test cases/failing/49 pkgconfig variables not key value/test.json
@@ -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."
}
]
}