aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Pkgconfig-module.md12
-rw-r--r--docs/markdown/snippets/pkgconfig_var_escaping.md23
-rw-r--r--mesonbuild/modules/pkgconfig.py18
-rwxr-xr-xrun_unittests.py2
-rw-r--r--test cases/common/44 pkgconfig-gen/meson.build4
5 files changed, 52 insertions, 7 deletions
diff --git a/docs/markdown/Pkgconfig-module.md b/docs/markdown/Pkgconfig-module.md
index 9c66b33..0d1e859 100644
--- a/docs/markdown/Pkgconfig-module.md
+++ b/docs/markdown/Pkgconfig-module.md
@@ -55,12 +55,20 @@ keyword arguments.
`includedir` are reserved and may not be used. *Since 0.56.0* it can also be a
dictionary but ordering of Meson dictionaries are not guaranteed, which could
cause issues when some variables reference other variables.
+ Spaces in values are escaped with `\`, this is required in the case the value is
+ a path that and is used in `cflags` or `libs` arguments. *Since 0.59.0* if
+ escaping is not desired (e.g. space separate list of values) `unescaped_variables`
+ keyword argument should be used instead.
+- `uninstalled_variables` used instead of the `variables` keyword argument, when
+ generating the uninstalled pkg-config file. Since *0.54.0*
+ Spaces in values are escaped with `\`, this is required in the case the value is
+ a path that and is used in `cflags` or `libs` arguments. *Since 0.59.0* if
+ escaping is not desired (e.g. space separate list of values)
+ `unescaped_uninstalled_variables` keyword argument should be used instead.
- `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
D sources referred to by this pkg-config file
-- `uninstalled_variables` used instead of the `variables` keyword argument, when
- generating the uninstalled pkg-config file. Since *0.54.0*
- `dataonly` field. (*since 0.54.0*) this is used for architecture-independent
pkg-config files in projects which also have architecture-dependent outputs.
- `conflicts` (*since 0.36.0, incorrectly issued a warning prior to 0.54.0*) list of strings to be put in the `Conflicts` field.
diff --git a/docs/markdown/snippets/pkgconfig_var_escaping.md b/docs/markdown/snippets/pkgconfig_var_escaping.md
new file mode 100644
index 0000000..de0ee96
--- /dev/null
+++ b/docs/markdown/snippets/pkgconfig_var_escaping.md
@@ -0,0 +1,23 @@
+## Unescaped variables in pkgconfig files
+
+Spaces in variable values are escaped with `\`, this is required in the case the
+value is a path that and is used in `cflags` or `libs` arguments. This was an
+undocumented behaviour that caused issues in the case the variable is a space
+separated list of items.
+
+For backward compatibility reasons this behaviour could not be changed, new
+keyword arguments have thus been added: `unescaped_variables` and
+`unescaped_uninstalled_variables`.
+
+```meson
+pkg = import('pkgconfig')
+...
+pkg.generate(lib,
+ variables: {
+ 'mypath': '/path/with spaces/are/escaped',
+ },
+ unescaped_variables: {
+ 'mylist': 'Hello World Is Not Escaped',
+ },
+)
+```
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
index 18815f6..c9d5361 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -327,7 +327,7 @@ class PkgConfigModule(ExtensionModule):
def generate_pkgconfig_file(self, state, deps, subdirs, name, description,
url, version, pcfile, conflicts, variables,
- uninstalled=False, dataonly=False):
+ unescaped_variables, uninstalled=False, dataonly=False):
coredata = state.environment.get_coredata()
if uninstalled:
outdir = os.path.join(state.environment.build_dir, 'meson-uninstalled')
@@ -349,10 +349,12 @@ class PkgConfigModule(ExtensionModule):
ofile.write('srcdir={}\n'.format(self._escape(srcdir)))
ofile.write('libdir={}\n'.format(self._escape('${prefix}' / libdir)))
ofile.write('includedir={}\n'.format(self._escape('${prefix}' / incdir)))
- if variables:
+ if variables or unescaped_variables:
ofile.write('\n')
for k, v in variables:
ofile.write('{}={}\n'.format(k, self._escape(v)))
+ for k, v in unescaped_variables:
+ ofile.write(f'{k}={v}\n')
ofile.write('\n')
ofile.write('Name: %s\n' % name)
if len(description) > 0:
@@ -445,6 +447,7 @@ class PkgConfigModule(ExtensionModule):
if cflags and not dataonly:
ofile.write('Cflags: {}\n'.format(' '.join(cflags)))
+ @FeatureNewKwargs('pkgconfig.generate', '0.59.0', ['unescaped_variables', 'unescaped_uninstalled_variables'])
@FeatureNewKwargs('pkgconfig.generate', '0.54.0', ['uninstalled_variables'])
@FeatureNewKwargs('pkgconfig.generate', '0.42.0', ['extra_cflags'])
@FeatureNewKwargs('pkgconfig.generate', '0.41.0', ['variables'])
@@ -452,7 +455,8 @@ class PkgConfigModule(ExtensionModule):
@permittedKwargs({'libraries', 'version', 'name', 'description', 'filebase',
'subdirs', 'requires', 'requires_private', 'libraries_private',
'install_dir', 'extra_cflags', 'variables', 'url', 'd_module_versions',
- 'dataonly', 'conflicts', 'uninstalled_variables'})
+ 'dataonly', 'conflicts', 'uninstalled_variables',
+ 'unescaped_variables', 'unescaped_uninstalled_variables'})
def generate(self, state, args, kwargs):
default_version = state.project_version['version']
default_install_dir = None
@@ -535,6 +539,8 @@ class PkgConfigModule(ExtensionModule):
variables = self.interpreter.extract_variables(kwargs, dict_new=True)
variables = parse_variable_list(variables)
+ unescaped_variables = self.interpreter.extract_variables(kwargs, argname='unescaped_variables')
+ unescaped_variables = parse_variable_list(unescaped_variables)
pcfile = filebase + '.pc'
pkgroot = kwargs.get('install_dir', default_install_dir)
@@ -547,15 +553,17 @@ class PkgConfigModule(ExtensionModule):
raise mesonlib.MesonException('Install_dir must be a string.')
self.generate_pkgconfig_file(state, deps, subdirs, name, description, url,
version, pcfile, conflicts, variables,
- False, dataonly)
+ unescaped_variables, False, dataonly)
res = build.Data([mesonlib.File(True, state.environment.get_scratch_dir(), pcfile)], pkgroot, None, state.subproject)
variables = self.interpreter.extract_variables(kwargs, argname='uninstalled_variables', dict_new=True)
variables = parse_variable_list(variables)
+ unescaped_variables = self.interpreter.extract_variables(kwargs, argname='unescaped_uninstalled_variables')
+ unescaped_variables = parse_variable_list(unescaped_variables)
pcfile = filebase + '-uninstalled.pc'
self.generate_pkgconfig_file(state, deps, subdirs, name, description, url,
version, pcfile, conflicts, variables,
- uninstalled=True, dataonly=dataonly)
+ unescaped_variables, uninstalled=True, dataonly=dataonly)
# Associate the main library with this generated pc file. If the library
# is used in any subsequent call to the generated, it will generate a
# 'Requires:' or 'Requires.private:'.
diff --git a/run_unittests.py b/run_unittests.py
index fe664cb..f65eba3 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -6545,6 +6545,8 @@ class LinuxlikeTests(BasePlatformTests):
self.assertEqual(libhello_nolib.get_compile_args(), [])
self.assertEqual(libhello_nolib.get_pkgconfig_variable('foo', {}), 'bar')
self.assertEqual(libhello_nolib.get_pkgconfig_variable('prefix', {}), self.prefix)
+ self.assertEqual(libhello_nolib.get_pkgconfig_variable('escaped_var', {}), 'hello\ world')
+ self.assertEqual(libhello_nolib.get_pkgconfig_variable('unescaped_var', {}), 'hello world')
cc = env.detect_c_compiler(MachineChoice.HOST)
if cc.get_id() in {'gcc', 'clang'}:
diff --git a/test cases/common/44 pkgconfig-gen/meson.build b/test cases/common/44 pkgconfig-gen/meson.build
index 7885391..64965bc 100644
--- a/test cases/common/44 pkgconfig-gen/meson.build
+++ b/test cases/common/44 pkgconfig-gen/meson.build
@@ -70,7 +70,11 @@ pkgg.generate(
# prefix is not set by default for dataonly pc files, but it is allowed to
# define it manually.
'prefix': get_option('prefix'),
+ 'escaped_var': 'hello world',
},
+ unescaped_variables: {
+ 'unescaped_var': 'hello world',
+ }
)
# Regression test for 2 cases: