Merge pull request #899 from centricular/pkgconfig-allow-libfoo-name
pkgconfig: Handle library names starting with 'lib'
This commit is contained in:
commit
abfc95e75a
|
@ -87,6 +87,7 @@ class PkgConfigDependency(Dependency):
|
|||
self.is_libtool = False
|
||||
self.required = kwargs.get('required', True)
|
||||
self.static = kwargs.get('static', False)
|
||||
self.silent = kwargs.get('silent', False)
|
||||
if not isinstance(self.static, bool):
|
||||
raise DependencyException('Static keyword must be boolean')
|
||||
self.cargs = []
|
||||
|
@ -115,16 +116,12 @@ class PkgConfigDependency(Dependency):
|
|||
|
||||
mlog.debug('Determining dependency %s with pkg-config executable %s.' % (name, pkgbin))
|
||||
self.pkgbin = pkgbin
|
||||
p = subprocess.Popen([pkgbin, '--modversion', name],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
out = p.communicate()[0]
|
||||
if p.returncode != 0:
|
||||
ret, self.modversion = self._call_pkgbin(['--modversion', name])
|
||||
if ret != 0:
|
||||
if self.required:
|
||||
raise DependencyException('%s dependency %s not found.' % (self.type_string, name))
|
||||
self.modversion = 'none'
|
||||
return
|
||||
self.modversion = out.decode().strip()
|
||||
found_msg = ['%s dependency' % self.type_string, mlog.bold(name), 'found:']
|
||||
self.version_requirement = kwargs.get('version', None)
|
||||
if self.version_requirement is None:
|
||||
|
@ -136,40 +133,45 @@ class PkgConfigDependency(Dependency):
|
|||
if not self.is_found:
|
||||
found_msg += [mlog.red('NO'), 'found {!r}'.format(self.modversion),
|
||||
'but need {!r}'.format(self.version_requirement)]
|
||||
mlog.log(*found_msg)
|
||||
if not self.silent:
|
||||
mlog.log(*found_msg)
|
||||
if self.required:
|
||||
raise DependencyException(
|
||||
'Invalid version of a dependency, needed %s %s found %s.' %
|
||||
(name, self.version_requirement, self.modversion))
|
||||
return
|
||||
found_msg += [mlog.green('YES'), self.modversion]
|
||||
mlog.log(*found_msg)
|
||||
if not self.silent:
|
||||
mlog.log(*found_msg)
|
||||
# Fetch cargs to be used while using this dependency
|
||||
self._set_cargs()
|
||||
# Fetch the libraries and library paths needed for using this
|
||||
self._set_libs()
|
||||
|
||||
def _set_cargs(self):
|
||||
p = subprocess.Popen([self.pkgbin, '--cflags', self.name],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
def _call_pkgbin(self, args):
|
||||
p = subprocess.Popen([self.pkgbin] + args,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
env=os.environ, universal_newlines=True)
|
||||
out = p.communicate()[0]
|
||||
if p.returncode != 0:
|
||||
return (p.returncode, out.strip())
|
||||
|
||||
def _set_cargs(self):
|
||||
ret, out = self._call_pkgbin(['--cflags', self.name])
|
||||
if ret != 0:
|
||||
raise DependencyException('Could not generate cargs for %s:\n\n%s' % \
|
||||
(self.name, out.decode(errors='ignore')))
|
||||
self.cargs = out.decode().split()
|
||||
self.cargs = out.split()
|
||||
|
||||
def _set_libs(self):
|
||||
libcmd = [self.pkgbin, '--libs']
|
||||
libcmd = [self.name, '--libs']
|
||||
if self.static:
|
||||
libcmd.append('--static')
|
||||
p = subprocess.Popen(libcmd + [self.name],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
out = p.communicate()[0]
|
||||
if p.returncode != 0:
|
||||
ret, out = self._call_pkgbin(libcmd)
|
||||
if ret != 0:
|
||||
raise DependencyException('Could not generate libs for %s:\n\n%s' % \
|
||||
(self.name, out.decode(errors='ignore')))
|
||||
self.libs = []
|
||||
for lib in out.decode().split():
|
||||
for lib in out.split():
|
||||
if lib.endswith(".la"):
|
||||
shared_libname = self.extract_libtool_shlib(lib)
|
||||
shared_lib = os.path.join(os.path.dirname(lib), shared_libname)
|
||||
|
@ -185,16 +187,14 @@ class PkgConfigDependency(Dependency):
|
|||
self.libs.append(lib)
|
||||
|
||||
def get_variable(self, variable_name):
|
||||
p = subprocess.Popen([self.pkgbin, '--variable=%s' % variable_name, self.name],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
out = p.communicate()[0]
|
||||
ret, out = self._call_pkgbin(['--variable=' + variable_name, self.name])
|
||||
variable = ''
|
||||
if p.returncode != 0:
|
||||
if ret != 0:
|
||||
if self.required:
|
||||
raise DependencyException('%s dependency %s not found.' %
|
||||
(self.type_string, self.name))
|
||||
else:
|
||||
variable = out.decode().strip()
|
||||
variable = out.strip()
|
||||
mlog.debug('return of subprocess : %s' % variable)
|
||||
|
||||
return variable
|
||||
|
@ -217,14 +217,16 @@ class PkgConfigDependency(Dependency):
|
|||
stderr=subprocess.PIPE)
|
||||
out = p.communicate()[0]
|
||||
if p.returncode == 0:
|
||||
mlog.log('Found pkg-config:', mlog.bold(shutil.which('pkg-config')),
|
||||
'(%s)' % out.decode().strip())
|
||||
if not self.silent:
|
||||
mlog.log('Found pkg-config:', mlog.bold(shutil.which('pkg-config')),
|
||||
'(%s)' % out.decode().strip())
|
||||
PkgConfigDependency.pkgconfig_found = True
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
PkgConfigDependency.pkgconfig_found = False
|
||||
mlog.log('Found Pkg-config:', mlog.red('NO'))
|
||||
if not self.silent:
|
||||
mlog.log('Found Pkg-config:', mlog.red('NO'))
|
||||
|
||||
def found(self):
|
||||
return self.is_found
|
||||
|
|
|
@ -19,6 +19,24 @@ import os
|
|||
|
||||
class PkgConfigModule:
|
||||
|
||||
def _get_lname(self, l, msg, pcfile):
|
||||
# Nothing special
|
||||
if not l.name_prefix_set:
|
||||
return l.name
|
||||
# Sometimes people want the library to start with 'lib' everywhere,
|
||||
# which is achieved by setting name_prefix to '' and the target name to
|
||||
# 'libfoo'. In that case, try to get the pkg-config '-lfoo' arg correct.
|
||||
if l.prefix == '' and l.name.startswith('lib'):
|
||||
return l.name[3:]
|
||||
# If the library is imported via an import library which is always
|
||||
# named after the target name, '-lfoo' is correct.
|
||||
if l.import_filename:
|
||||
return l.name
|
||||
# In other cases, we can't guarantee that the compiler will be able to
|
||||
# find the library via '-lfoo', so tell the user that.
|
||||
mlog.log(mlog.red('WARNING:'), msg.format(l.name, 'name_prefix', l.name, pcfile))
|
||||
return l.name
|
||||
|
||||
def generate_pkgconfig_file(self, state, libraries, subdirs, name, description, version, pcfile,
|
||||
pub_reqs, priv_reqs, priv_libs):
|
||||
coredata = state.environment.get_coredata()
|
||||
|
@ -45,20 +63,17 @@ class PkgConfigModule:
|
|||
'Libraries.private: {}\n'.format(' '.join(priv_libs)))
|
||||
ofile.write('Libs: -L${libdir} ')
|
||||
msg = 'Library target {0!r} has {1!r} set. Compilers ' \
|
||||
'may not find it from its \'-l{0}\' linker flag in the ' \
|
||||
'{2!r} pkg-config file.'
|
||||
'may not find it from its \'-l{2}\' linker flag in the ' \
|
||||
'{3!r} pkg-config file.'
|
||||
for l in libraries:
|
||||
if l.custom_install_dir:
|
||||
ofile.write('-L${prefix}/%s ' % l.custom_install_dir)
|
||||
# Warn, but not if the filename starts with 'lib'. This can
|
||||
# happen, for instance, if someone really wants to use the
|
||||
# 'lib' prefix on all systems, not just on UNIX, or if the the
|
||||
# target name itself starts with 'lib'.
|
||||
if l.name_prefix_set and not l.filename.startswith('lib'):
|
||||
mlog.log(mlog.red('WARNING:'), msg.format(l.name, 'name_prefix', pcfile))
|
||||
lname = self._get_lname(l, msg, pcfile)
|
||||
# If using a custom suffix, the compiler may not be able to
|
||||
# find the library
|
||||
if l.name_suffix_set:
|
||||
mlog.log(mlog.red('WARNING:'), msg.format(l.name, 'name_suffix', pcfile))
|
||||
ofile.write('-l%s ' % l.name)
|
||||
mlog.log(mlog.red('WARNING:'), msg.format(l.name, 'name_suffix', lname, pcfile))
|
||||
ofile.write('-l{} '.format(lname))
|
||||
ofile.write('\n')
|
||||
ofile.write('CFlags: ')
|
||||
for h in subdirs:
|
||||
|
|
|
@ -18,6 +18,7 @@ import subprocess
|
|||
import re, json
|
||||
import tempfile
|
||||
from mesonbuild.environment import detect_ninja
|
||||
from mesonbuild.dependencies import PkgConfigDependency
|
||||
|
||||
def get_soname(fname):
|
||||
# HACK, fix to not use shell.
|
||||
|
@ -28,6 +29,13 @@ def get_soname(fname):
|
|||
if m is not None:
|
||||
return m.group(1)
|
||||
|
||||
class FakeEnvironment(object):
|
||||
def __init__(self):
|
||||
self.cross_info = None
|
||||
|
||||
def is_cross_build(self):
|
||||
return False
|
||||
|
||||
class LinuxlikeTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
@ -38,9 +46,11 @@ class LinuxlikeTests(unittest.TestCase):
|
|||
self.ninja_command = [detect_ninja(), '-C', self.builddir]
|
||||
self.common_test_dir = os.path.join(src_root, 'test cases/common')
|
||||
self.output = b''
|
||||
self.orig_env = os.environ.copy()
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.builddir)
|
||||
os.environ = self.orig_env
|
||||
super().tearDown()
|
||||
|
||||
def init(self, srcdir):
|
||||
|
@ -87,5 +97,16 @@ class LinuxlikeTests(unittest.TestCase):
|
|||
compdb = self.get_compdb()
|
||||
self.assertTrue('-fPIC' not in compdb[0]['command'])
|
||||
|
||||
def test_pkgconfig_gen(self):
|
||||
testdir = os.path.join(self.common_test_dir, '51 pkgconfig-gen')
|
||||
self.init(testdir)
|
||||
env = FakeEnvironment()
|
||||
kwargs = {'required': True, 'silent': True}
|
||||
os.environ['PKG_CONFIG_LIBDIR'] = os.path.join(self.builddir, 'meson-private')
|
||||
simple_dep = PkgConfigDependency('libfoo', env, kwargs)
|
||||
self.assertTrue(simple_dep.found())
|
||||
self.assertEqual(simple_dep.get_version(), '1.0')
|
||||
self.assertTrue('-lfoo' in simple_dep.get_link_args())
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
usr/include/simple.h
|
||||
usr/lib/pkgconfig/simple.pc
|
||||
usr/lib/pkgconfig/libfoo.pc
|
||||
|
|
|
@ -15,5 +15,15 @@ pkgg.generate(
|
|||
description : 'A simple demo library.',
|
||||
requires : 'glib-2.0', # Not really, but only here to test that this works.
|
||||
requires_private : ['gio-2.0', 'gobject-2.0'],
|
||||
libraries_private : '-lz',
|
||||
)
|
||||
libraries_private : '-lz')
|
||||
|
||||
# Test that name_prefix='' and name='libfoo' results in '-lfoo'
|
||||
lib2 = shared_library('libfoo', 'simple.c',
|
||||
name_prefix : '',
|
||||
version : libver)
|
||||
|
||||
pkgg.generate(
|
||||
libraries : lib2,
|
||||
name : 'libfoo',
|
||||
version : libver,
|
||||
description : 'A foo library.')
|
||||
|
|
Loading…
Reference in New Issue