aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2016-06-05 13:51:03 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2016-06-05 13:51:03 +0300
commitbcec44b93ba9886f0981f8c1a509d08ec8caf07f (patch)
treec4e8e3320787fdf07d863362a4ce72307ad76d72
parent0bc00560644d20daee626533fc6e6294d92caa78 (diff)
parentfdc95c2ea413ad9d13b5cc3385fd0904b3361837 (diff)
downloadmeson-bcec44b93ba9886f0981f8c1a509d08ec8caf07f.zip
meson-bcec44b93ba9886f0981f8c1a509d08ec8caf07f.tar.gz
meson-bcec44b93ba9886f0981f8c1a509d08ec8caf07f.tar.bz2
Merge pull request #573 from centricular/dependency-versions
Several fixes to how versioned dependencies are handled + tests
-rw-r--r--mesonbuild/dependencies.py10
-rw-r--r--mesonbuild/interpreter.py36
-rw-r--r--mesonbuild/mesonlib.py2
-rw-r--r--test cases/linuxlike/5 dependency versions/meson.build28
-rw-r--r--test cases/linuxlike/5 dependency versions/subprojects/somelib/lib.c0
-rw-r--r--test cases/linuxlike/5 dependency versions/subprojects/somelib/meson.build8
-rw-r--r--test cases/linuxlike/5 dependency versions/subprojects/somelibnover/lib.c0
-rw-r--r--test cases/linuxlike/5 dependency versions/subprojects/somelibnover/meson.build8
-rw-r--r--test cases/linuxlike/5 dependency versions/subprojects/somelibver/lib.c0
-rw-r--r--test cases/linuxlike/5 dependency versions/subprojects/somelibver/meson.build9
10 files changed, 91 insertions, 10 deletions
diff --git a/mesonbuild/dependencies.py b/mesonbuild/dependencies.py
index 7462bd8..271c6b4 100644
--- a/mesonbuild/dependencies.py
+++ b/mesonbuild/dependencies.py
@@ -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)
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index ba943e3..47ed61c 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -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)
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index 584b3b2..837f78a 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -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
diff --git a/test cases/linuxlike/5 dependency versions/meson.build b/test cases/linuxlike/5 dependency versions/meson.build
new file mode 100644
index 0000000..abe3ea6
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/meson.build
@@ -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')
diff --git a/test cases/linuxlike/5 dependency versions/subprojects/somelib/lib.c b/test cases/linuxlike/5 dependency versions/subprojects/somelib/lib.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/subprojects/somelib/lib.c
diff --git a/test cases/linuxlike/5 dependency versions/subprojects/somelib/meson.build b/test cases/linuxlike/5 dependency versions/subprojects/somelib/meson.build
new file mode 100644
index 0000000..049c58b
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/subprojects/somelib/meson.build
@@ -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)
diff --git a/test cases/linuxlike/5 dependency versions/subprojects/somelibnover/lib.c b/test cases/linuxlike/5 dependency versions/subprojects/somelibnover/lib.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/subprojects/somelibnover/lib.c
diff --git a/test cases/linuxlike/5 dependency versions/subprojects/somelibnover/meson.build b/test cases/linuxlike/5 dependency versions/subprojects/somelibnover/meson.build
new file mode 100644
index 0000000..826bb3c
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/subprojects/somelibnover/meson.build
@@ -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)
diff --git a/test cases/linuxlike/5 dependency versions/subprojects/somelibver/lib.c b/test cases/linuxlike/5 dependency versions/subprojects/somelibver/lib.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/subprojects/somelibver/lib.c
diff --git a/test cases/linuxlike/5 dependency versions/subprojects/somelibver/meson.build b/test cases/linuxlike/5 dependency versions/subprojects/somelibver/meson.build
new file mode 100644
index 0000000..ad9f243
--- /dev/null
+++ b/test cases/linuxlike/5 dependency versions/subprojects/somelibver/meson.build
@@ -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')