Introduce dataonly for the pkgconfig module

This allows users to disable writing out the inbuilt variables to
the pkg-config file as they might actualy not be required.

One reason to have this is for architecture-independent pkg-config
files in projects which also have architecture-dependent outputs.

For example : https://gitlab.freedesktop.org/wayland/weston/issues/269

Fixes #4011
pull/6665/head
Rohan Garg 6 years ago committed by Xavier Claessens
parent 8d63b6340b
commit 73f03e6093
  1. 2
      docs/markdown/Pkgconfig-module.md
  2. 15
      docs/markdown/snippets/pkgconfig_dataonly.md
  3. 60
      mesonbuild/modules/pkgconfig.py
  4. 5
      run_unittests.py
  5. 1
      test cases/common/47 pkgconfig-gen/installed_files.txt
  6. 7
      test cases/common/47 pkgconfig-gen/meson.build

@ -56,6 +56,8 @@ keyword arguments.
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.
Since 0.46 a `StaticLibrary` or `SharedLibrary` object can optionally be passed
as first positional argument. If one is provided a default value will be

@ -0,0 +1,15 @@
## Introduce dataonly for the pkgconfig module
This allows users to disable writing out the inbuilt variables to
the pkg-config file as they might actualy not be required.
One reason to have this is for architecture-independent pkg-config
files in projects which also have architecture-dependent outputs.
```
pkgg.generate(
name : 'libhello_nolib',
description : 'A minimalistic pkgconfig file.',
version : libver,
dataonly: true
)
```

@ -266,7 +266,7 @@ class PkgConfigModule(ExtensionModule):
def generate_pkgconfig_file(self, state, deps, subdirs, name, description,
url, version, pcfile, conflicts, variables,
uninstalled=False):
uninstalled=False, dataonly=False):
deps.remove_dups()
coredata = state.environment.get_coredata()
if uninstalled:
@ -283,12 +283,13 @@ class PkgConfigModule(ExtensionModule):
incdir = PurePath(coredata.get_builtin_option('includedir'))
fname = os.path.join(outdir, pcfile)
with open(fname, 'w', encoding='utf-8') as ofile:
ofile.write('prefix={}\n'.format(self._escape(prefix)))
if uninstalled:
ofile.write('srcdir={}\n'.format(self._escape(srcdir)))
else:
ofile.write('libdir={}\n'.format(self._escape('${prefix}' / libdir)))
ofile.write('includedir={}\n'.format(self._escape('${prefix}' / incdir)))
if not dataonly:
ofile.write('prefix={}\n'.format(self._escape(prefix)))
if uninstalled:
ofile.write('srcdir={}\n'.format(self._escape(srcdir)))
else:
ofile.write('libdir={}\n'.format(self._escape('${prefix}' / libdir)))
ofile.write('includedir={}\n'.format(self._escape('${prefix}' / incdir)))
if variables:
ofile.write('\n')
for k, v in variables:
@ -370,27 +371,28 @@ class PkgConfigModule(ExtensionModule):
ofile.write('Libs: {}\n'.format(' '.join(generate_libs_flags(deps.pub_libs))))
if len(deps.priv_libs) > 0:
ofile.write('Libs.private: {}\n'.format(' '.join(generate_libs_flags(deps.priv_libs))))
def generate_compiler_flags():
cflags_buf = []
for f in deps.cflags:
cflags_buf.append(self._escape(f))
return cflags_buf
cflags = generate_compiler_flags()
ofile.write('Cflags:')
if uninstalled:
ofile.write(' '.join(generate_uninstalled_cflags(deps.pub_libs + deps.priv_libs)))
else:
for h in subdirs:
ofile.write(' ')
if h == '.':
ofile.write('-I${includedir}')
else:
ofile.write(self._escape(PurePath('-I${includedir}') / h))
for f in deps.cflags:
ofile.write(' ')
ofile.write(self._escape(f))
ofile.write('\n')
elif not dataonly and cflags:
ofile.write('{}\n'.format(' '.join(cflags)))
@FeatureNewKwargs('pkgconfig.generate', '0.54.0', ['uninstalled_variables'])
@FeatureNewKwargs('pkgconfig.generate', '0.42.0', ['extra_cflags'])
@FeatureNewKwargs('pkgconfig.generate', '0.41.0', ['variables'])
@FeatureNewKwargs('pkgconfig.generate', '0.54.0', ['dataonly'])
@permittedKwargs({'libraries', 'version', 'name', 'description', 'filebase',
'subdirs', 'requires', 'requires_private', 'libraries_private',
'install_dir', 'extra_cflags', 'variables', 'url', 'd_module_versions'})
'install_dir', 'extra_cflags', 'variables', 'url', 'd_module_versions',
'dataonly'})
def generate(self, state, args, kwargs):
if 'variables' in kwargs:
FeatureNew('custom pkgconfig variables', '0.41.0').use(state.subproject)
@ -399,6 +401,7 @@ class PkgConfigModule(ExtensionModule):
default_description = None
default_name = None
mainlib = None
default_subdirs = ['.']
if not args and 'version' not in kwargs:
FeatureNew('pkgconfig.generate implicit version keyword', '0.46.0').use(state.subproject)
elif len(args) == 1:
@ -414,7 +417,14 @@ class PkgConfigModule(ExtensionModule):
elif len(args) > 1:
raise mesonlib.MesonException('Too many positional arguments passed to Pkgconfig_gen.')
subdirs = mesonlib.stringlistify(kwargs.get('subdirs', ['.']))
dataonly = kwargs.get('dataonly', False)
if dataonly:
default_subdirs = []
blocked_vars = ['libraries', 'libraries_private', 'require_private', 'extra_cflags', 'subdirs']
if len(set(kwargs) & set(blocked_vars)) > 0:
raise mesonlib.MesonException('Cannot combine dataonly with any of {}'.format(blocked_vars))
subdirs = mesonlib.stringlistify(kwargs.get('subdirs', default_subdirs))
version = kwargs.get('version', default_version)
if not isinstance(version, str):
raise mesonlib.MesonException('Version must be specified.')
@ -440,6 +450,11 @@ class PkgConfigModule(ExtensionModule):
libraries = [mainlib] + libraries
deps = DependenciesHelper(state, filebase)
for d in subdirs:
if d == '.':
deps.add_cflags(['-I${includedir}'])
else:
deps.add_cflags(self._escape(PurePath('-I${includedir}') / d))
deps.add_pub_libs(libraries)
deps.add_priv_libs(kwargs.get('libraries_private', []))
deps.add_pub_reqs(kwargs.get('requires', []))
@ -488,13 +503,14 @@ class PkgConfigModule(ExtensionModule):
if not isinstance(pkgroot, str):
raise mesonlib.MesonException('Install_dir must be a string.')
self.generate_pkgconfig_file(state, deps, subdirs, name, description, url,
version, pcfile, conflicts, variables)
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', [])))
pcfile = filebase + '-uninstalled.pc'
self.generate_pkgconfig_file(state, deps, subdirs, name, description, url,
version, pcfile, conflicts, variables,
uninstalled=True)
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:'.

@ -4969,6 +4969,11 @@ class LinuxlikeTests(BasePlatformTests):
self.assertEqual(foo_dep.get_pkgconfig_variable('foo', {}), 'bar')
self.assertPathEqual(foo_dep.get_pkgconfig_variable('datadir', {}), '/usr/data')
libhello_nolib = PkgConfigDependency('libhello_nolib', env, kwargs)
self.assertTrue(libhello_nolib.found())
self.assertEqual(libhello_nolib.get_link_args(), [])
self.assertEqual(libhello_nolib.get_compile_args(), [])
def test_pkgconfig_gen_deps(self):
'''
Test that generated pkg-config files correctly handle dependencies

@ -2,3 +2,4 @@ usr/include/simple.h
usr/lib/pkgconfig/simple.pc
usr/lib/pkgconfig/libfoo.pc
usr/lib/pkgconfig/libhello.pc
usr/lib/pkgconfig/libhello_nolib.pc

@ -51,3 +51,10 @@ pkgg.generate(
description : 'A minimalistic pkgconfig file.',
version : libver,
)
pkgg.generate(
name : 'libhello_nolib',
description : 'A minimalistic pkgconfig file.',
version : libver,
dataonly: true
)

Loading…
Cancel
Save