Merge pull request #573 from centricular/dependency-versions

Several fixes to how versioned dependencies are handled + tests
pull/582/head
Jussi Pakkanen 9 years ago
commit bcec44b93b
  1. 10
      mesonbuild/dependencies.py
  2. 36
      mesonbuild/interpreter.py
  3. 2
      mesonbuild/mesonlib.py
  4. 28
      test cases/linuxlike/5 dependency versions/meson.build
  5. 0
      test cases/linuxlike/5 dependency versions/subprojects/somelib/lib.c
  6. 8
      test cases/linuxlike/5 dependency versions/subprojects/somelib/meson.build
  7. 0
      test cases/linuxlike/5 dependency versions/subprojects/somelibnover/lib.c
  8. 8
      test cases/linuxlike/5 dependency versions/subprojects/somelibnover/meson.build
  9. 0
      test cases/linuxlike/5 dependency versions/subprojects/somelibver/lib.c
  10. 9
      test cases/linuxlike/5 dependency versions/subprojects/somelibver/meson.build

@ -1148,7 +1148,15 @@ def get_dep_identifier(name, kwargs):
modlist = [modlist]
for module in modlist:
elements.append(module)
return '/'.join(elements) + '/main' + str(kwargs.get('main', False)) + '/static' + str(kwargs.get('static', False))
# We use a tuple because we need a non-mutable structure to use as the key
# of a dictionary and a string has potential for name collisions
identifier = tuple(elements)
identifier += ('main', kwargs.get('main', False))
identifier += ('static', kwargs.get('static', False))
if 'fallback' in kwargs:
f = kwargs.get('fallback')
identifier += ('fallback', f[0], f[1])
return identifier
def find_external_dependency(name, environment, kwargs):
required = kwargs.get('required', True)

@ -1188,7 +1188,7 @@ class Interpreter():
@noPosargs
def func_declare_dependency(self, node, args, kwargs):
version = kwargs.get('version', 'undefined')
version = kwargs.get('version', self.project_version)
if not isinstance(version, str):
raise InterpreterException('Version must be a string.')
incs = kwargs.get('include_directories', [])
@ -1358,7 +1358,7 @@ class Interpreter():
if 'version' in kwargs:
pv = subi.project_version
wanted = kwargs['version']
if not mesonlib.version_compare(pv, wanted):
if pv == 'undefined' or not mesonlib.version_compare(pv, wanted):
raise InterpreterException('Subproject %s version is %s but %s required.' % (dirname, pv, wanted))
self.active_projectname = current_active
mlog.log('\nSubproject', mlog.bold(dirname), 'finished.')
@ -1621,16 +1621,28 @@ class Interpreter():
self.validate_arguments(args, 1, [str])
name = args[0]
identifier = dependencies.get_dep_identifier(name, kwargs)
# Check if we've already searched for and found this dep
cached_dep = None
if identifier in self.coredata.deps:
dep = self.coredata.deps[identifier]
cached_dep = self.coredata.deps[identifier]
if 'version' in kwargs:
wanted = kwargs['version']
found = cached_dep.get_version()
if not found or not mesonlib.version_compare(found, wanted):
# Cached dep has the wrong version. Check if an external
# dependency or a fallback dependency provides it.
cached_dep = None
if cached_dep:
dep = cached_dep
else:
dep = dependencies.Dependency() # Returns always false for dep.found()
if not dep.found():
# We need to actually search for this dep
try:
dep = dependencies.find_external_dependency(name, self.environment, kwargs)
except dependencies.DependencyException:
if 'fallback' in kwargs:
return self.dependency_fallback(kwargs)
dep = self.dependency_fallback(kwargs)
self.coredata.deps[identifier] = dep.held_object
return dep
raise
self.coredata.deps[identifier] = dep
return DependencyHolder(dep)
@ -1641,8 +1653,16 @@ class Interpreter():
if len(fbinfo) != 2:
raise InterpreterException('Fallback info must have exactly two items.')
dirname, varname = fbinfo
self.do_subproject(dirname, kwargs)
return self.subprojects[dirname].get_variable_method([varname], {})
self.do_subproject(dirname, {})
dep = self.subprojects[dirname].get_variable_method([varname], {})
# Check if the version of the declared dependency matches what we want
if 'version' in kwargs:
wanted = kwargs['version']
found = dep.version_method([], {})
if found == 'undefined' or not mesonlib.version_compare(found, wanted):
m = 'Subproject "{0}" dependency "{1}" version is "{2}" but "{3}" is required.'
raise InterpreterException(m.format(dirname, varname, found, wanted))
return dep
def func_executable(self, node, args, kwargs):
return self.build_target(node, args, kwargs, ExecutableHolder)

@ -132,7 +132,7 @@ numpart = re.compile('[0-9.]+')
def version_compare(vstr1, vstr2):
match = numpart.match(vstr1.strip())
if match is None:
raise MesonException('Unconparable version string %s.' % vstr1)
raise MesonException('Uncomparable version string %s.' % vstr1)
vstr1 = match.group(0)
if vstr2.startswith('>='):
cmpop = operator.ge

@ -0,0 +1,28 @@
project('dep versions', 'c')
# Find external dependency without version
zlib = dependency('zlib')
# Find external dependency with version
zlibver = dependency('zlib', version : '>1.0')
assert(zlib.version() == zlibver.version(), 'zlib versions did not match!')
# Find external dependency with conflicting version
zlibver = dependency('zlib', version : '<1.0', required : false)
assert(zlibver.found() == false, 'zlib <1.0 should not be found!')
# Find internal dependency without version
somelibver = dependency('somelib',
fallback : ['somelibnover', 'some_dep'])
# Find an internal dependency again with the same name and a specific version
somelib = dependency('somelib',
version : '== 0.1',
fallback : ['somelib', 'some_dep'])
# Find an internal dependency again with the same name and incompatible version
somelibver = dependency('somelib',
version : '>= 0.3',
fallback : ['somelibver', 'some_dep'])
# Find somelib again, but with a fallback that will fail
somelibfail = dependency('somelib',
version : '>= 0.2',
required : false,
fallback : ['somelibfail', 'some_dep'])
assert(somelibfail.found() == false, 'somelibfail found via wrong fallback')

@ -0,0 +1,8 @@
# Define version only in project, should get inherited by declare_dependency
project('some', 'c', version : '0.1')
somelib = shared_library('some', 'lib.c')
someinc = include_directories('.')
some_dep = declare_dependency(link_with : somelib,
include_directories : someinc)

@ -0,0 +1,8 @@
project('some', 'c')
somelib = shared_library('some', 'lib.c')
someinc = include_directories('.')
# Define version only in declare_dependency
some_dep = declare_dependency(link_with : somelib,
include_directories : someinc)

@ -0,0 +1,9 @@
project('some', 'c')
somelib = shared_library('some', 'lib.c')
someinc = include_directories('.')
# Define version only in declare_dependency
some_dep = declare_dependency(link_with : somelib,
include_directories : someinc,
version : '0.3')
Loading…
Cancel
Save