aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/snippets/pkgconfig_directory_variables.md31
-rw-r--r--mesonbuild/modules/pkgconfig.py57
-rw-r--r--test cases/common/44 pkgconfig-gen/meson.build16
-rw-r--r--test cases/common/44 pkgconfig-gen/test.json15
4 files changed, 107 insertions, 12 deletions
diff --git a/docs/markdown/snippets/pkgconfig_directory_variables.md b/docs/markdown/snippets/pkgconfig_directory_variables.md
new file mode 100644
index 0000000..27a4069
--- /dev/null
+++ b/docs/markdown/snippets/pkgconfig_directory_variables.md
@@ -0,0 +1,31 @@
+## pkgconfig.generate will now include variables for builtin directories when referenced
+
+When using the `variables:` family of kwargs to `pkgconfig.generate` to refer
+to installed paths, traditionally only `prefix`, `includedir`, and `libdir`
+were available by default, and generating a correct (relocatable) pkg-config
+file required manually constructing variables for e.g. `datadir`.
+
+Meson now checks each variable to see if it begins with a reference to a
+standard directory, and if so, adds it to the list of directories for which a
+builtin variable is created.
+
+For example, before it was necessary to do this:
+```meson
+pkgconfig.generate(
+ name: 'bash-completion',
+ description: 'programmable completion for the bash shell',
+ dataonly: true,
+ variables: {
+ 'prefix': get_option('prefix'),
+ 'datadir': join_paths('${prefix}', get_option('datadir')),
+ 'sysconfdir': join_paths('${prefix}', get_option('sysconfdir')),
+
+ 'compatdir': '${sysconfdir}/bash_completion.d',
+ 'completionsdir': '${datadir}/bash-completion/completions',
+ 'helpersdir': '${datadir}/bash-completion/helpers',
+ },
+ install_dir: join_paths(get_option('datadir'), 'pkgconfig'),
+)
+```
+
+Now the first three variables are not needed.
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
index 2e985cf..f67e6eb 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -22,8 +22,9 @@ from .. import build
from .. import dependencies
from .. import mesonlib
from .. import mlog
+from ..coredata import BUILTIN_DIR_OPTIONS
from ..dependencies import ThreadDependency
-from ..interpreterbase import permittedKwargs, FeatureNew, FeatureNewKwargs
+from ..interpreterbase import permittedKwargs, FeatureNew, FeatureDeprecated, FeatureNewKwargs
if T.TYPE_CHECKING:
from . import ModuleState
@@ -329,6 +330,41 @@ class PkgConfigModule(ExtensionModule):
url, version, pcfile, conflicts, variables,
unescaped_variables, uninstalled=False, dataonly=False):
coredata = state.environment.get_coredata()
+ referenced_vars = set()
+ optnames = [x.name for x in BUILTIN_DIR_OPTIONS.keys()]
+
+ if not dataonly:
+ # includedir is always implied, although libdir may not be
+ # needed for header-only libraries
+ referenced_vars |= {'prefix', 'includedir'}
+ if deps.pub_libs or deps.priv_libs:
+ referenced_vars |= {'libdir'}
+ # also automatically infer variables referenced in other variables
+ implicit_vars_warning = False
+ redundant_vars_warning = False
+ varnames = set()
+ varstrings = set()
+ for k, v in variables + unescaped_variables:
+ varnames |= {k}
+ varstrings |= {v}
+ for optname in optnames:
+ optvar = f'${{{optname}}}'
+ if any(x.startswith(optvar) for x in varstrings):
+ if optname in varnames:
+ redundant_vars_warning = True
+ else:
+ # these 3 vars were always "implicit"
+ if dataonly or optname not in {'prefix', 'includedir', 'libdir'}:
+ implicit_vars_warning = True
+ referenced_vars |= {'prefix', optname}
+ if redundant_vars_warning:
+ FeatureDeprecated.single_use('pkgconfig.generate variable for builtin directories', '0.62.0',
+ state.subproject, 'They will be automatically included when referenced',
+ state.current_node)
+ if implicit_vars_warning:
+ FeatureNew.single_use('pkgconfig.generate implicit variable for builtin directories', '0.62.0',
+ state.subproject, location=state.current_node)
+
if uninstalled:
outdir = os.path.join(state.environment.build_dir, 'meson-uninstalled')
if not os.path.exists(outdir):
@@ -338,18 +374,17 @@ class PkgConfigModule(ExtensionModule):
else:
outdir = state.environment.scratch_dir
prefix = PurePath(coredata.get_option(mesonlib.OptionKey('prefix')))
- # These always return paths relative to prefix
- libdir = PurePath(coredata.get_option(mesonlib.OptionKey('libdir')))
- incdir = PurePath(coredata.get_option(mesonlib.OptionKey('includedir')))
fname = os.path.join(outdir, pcfile)
with open(fname, 'w', encoding='utf-8') as ofile:
- if not dataonly:
- ofile.write('prefix={}\n'.format(self._escape(prefix)))
- if uninstalled:
- ofile.write('srcdir={}\n'.format(self._escape(srcdir)))
- if deps.pub_libs or deps.priv_libs:
- ofile.write('libdir={}\n'.format(self._escape('${prefix}' / libdir)))
- ofile.write('includedir={}\n'.format(self._escape('${prefix}' / incdir)))
+ for optname in optnames:
+ if optname in referenced_vars - varnames:
+ if optname == 'prefix':
+ ofile.write('prefix={}\n'.format(self._escape(prefix)))
+ else:
+ dirpath = PurePath(coredata.get_option(mesonlib.OptionKey(optname)))
+ ofile.write('{}={}\n'.format(optname, self._escape('${prefix}' / dirpath)))
+ if uninstalled and not dataonly:
+ ofile.write('srcdir={}\n'.format(self._escape(srcdir)))
if variables or unescaped_variables:
ofile.write('\n')
for k, v in variables:
diff --git a/test cases/common/44 pkgconfig-gen/meson.build b/test cases/common/44 pkgconfig-gen/meson.build
index 128205a..a24c239 100644
--- a/test cases/common/44 pkgconfig-gen/meson.build
+++ b/test cases/common/44 pkgconfig-gen/meson.build
@@ -1,4 +1,4 @@
-project('pkgconfig-gen', 'c')
+project('pkgconfig-gen', 'c', meson_version: '>=0.60.0')
# Some CI runners does not have zlib, just skip them as we need some common
# external dependency.
@@ -149,3 +149,17 @@ ct = custom_target('stat3',
)
simple6 = library('simple6', link_with: ct)
pkgg.generate(simple6)
+
+# implicit variables
+pkgg.generate(
+ name : 'libvartest',
+ description : 'Check that implicit vars are created',
+ version : libver,
+ variables: ['datadir=${prefix}/data', 'foo=${datadir}/foo', 'bar=${bindir}/bar']
+)
+pkgg.generate(
+ name : 'libvartest2',
+ description : 'Check that libdir is not an implicit var',
+ version : libver,
+ variables: ['bar=${libdir}/bar']
+)
diff --git a/test cases/common/44 pkgconfig-gen/test.json b/test cases/common/44 pkgconfig-gen/test.json
index c7bdd43..118fecd 100644
--- a/test cases/common/44 pkgconfig-gen/test.json
+++ b/test cases/common/44 pkgconfig-gen/test.json
@@ -7,11 +7,26 @@
{"type": "file", "file": "usr/lib/pkgconfig/libfoo.pc"},
{"type": "file", "file": "usr/lib/pkgconfig/libhello.pc"},
{"type": "file", "file": "usr/lib/pkgconfig/libhello_nolib.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/libvartest.pc"},
+ {"type": "file", "file": "usr/lib/pkgconfig/libvartest2.pc"},
{"type": "file", "file": "usr/lib/pkgconfig/simple2.pc"},
{"type": "file", "file": "usr/lib/pkgconfig/simple3.pc"},
{"type": "file", "file": "usr/lib/pkgconfig/simple5.pc"},
{"type": "file", "file": "usr/lib/pkgconfig/simple6.pc"},
{"type": "file", "file": "usr/lib/pkgconfig/ct.pc"},
{"type": "file", "file": "usr/lib/pkgconfig/ct0.pc"}
+ ],
+ "stdout": [
+ {
+ "line": "test cases/common/44 pkgconfig-gen/meson.build:158: WARNING: Project targeting '>=0.60.0' but tried to use feature introduced in '0.62.0': pkgconfig.generate implicit variable for builtin directories."
+ },
+ {
+ "line": "test cases/common/44 pkgconfig-gen/meson.build:164: WARNING: Project targeting '>=0.60.0' but tried to use feature introduced in '0.62.0': pkgconfig.generate implicit variable for builtin directories.",
+ "count": 0
+ },
+ {
+ "comment": "This will either match in the future-deprecated notice summary, or match the warning summary",
+ "line": " * 0.62.0: {'pkgconfig.generate variable for builtin directories'}"
+ }
]
}