pkgconfig module: allow custom variables to reference builtin directories
Automatically generate additional variables and write them into the
generated pkg-config file.
This means projects no longer need to manually define the ones they
use, which is annoying for dataonly usages (it used to forbid setting
the base library-relevant "reserved" ones, and now allows it only for
dataonly. But it's bloat to manualy list them anyway).
It also fixes a regression in commit
248e6cf473
which caused libdir to not be
set, and to be unsettable, if the pkg-config file has no libraries but
uses the ${libdir} expansion in a custom variable. This could be
considered likely a case for dataonly, but it's not guaranteed.
This commit is contained in:
parent
2d56ff135e
commit
6240920c21
|
@ -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.
|
|
@ -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:
|
||||
|
|
|
@ -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']
|
||||
)
|
||||
|
|
|
@ -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'}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue