summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-09-24 17:23:20 +0200
committerDylan Baker <dylan@pnwbakers.com>2025-10-14 09:35:56 -0700
commit16c5080a184f095dd721b719b5406128aee5e890 (patch)
tree31539a29d0f3df2fb8daa2875587554cca37c57f
parentf864690f3a74ed4f751e9b6d9a8855ec16030c65 (diff)
downloadmeson-16c5080a184f095dd721b719b5406128aee5e890.tar.gz
cargo: improve error message for dependency version conflicts
While developing I often got a confusing 'Neither a subproject directory nor a None.wrap file was found'. Replace it with a clear message that explains: 1. Which dependency couldn't be found 2. What versions are available in the root Cargo.lock 3. That this is likely a version conflict 4. How to fix it (update dependencies to match root Cargo.lock) Example: ERROR: Dependency 'socket2-0.4-rs' not found. Root Cargo.lock provides: socket2-0.5-rs, socket2-0.6-rs. This could be a Meson bug, please report it. I am actually not sure if this is really always a Meson bug. But to be safe, suggest reporting it until more experience is gained. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--mesonbuild/cargo/interpreter.py11
-rw-r--r--mesonbuild/cargo/manifest.py23
2 files changed, 33 insertions, 1 deletions
diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py
index be3d29337..74d7ae09f 100644
--- a/mesonbuild/cargo/interpreter.py
+++ b/mesonbuild/cargo/interpreter.py
@@ -124,6 +124,17 @@ class Interpreter:
def _fetch_package_from_subproject(self, package_name: str, meson_depname: str) -> T.Tuple[PackageState, bool]:
subp_name, _ = self.environment.wrap_resolver.find_dep_provider(meson_depname)
+ if subp_name is None:
+ # If Cargo.lock has a different version, this could be a resolution
+ # bug, but maybe also a version mismatch? I am not sure yet...
+ similar_deps = [pkg.subproject
+ for pkg in self.cargolock.named(package_name)]
+ if similar_deps:
+ similar_msg = f'Cargo.lock provides: {", ".join(similar_deps)}.'
+ else:
+ similar_msg = 'Cargo.lock does not contain this crate name.'
+ raise MesonException(f'Dependency {meson_depname!r} not found in any wrap files or Cargo.lock; {similar_msg} This could be a Meson bug, please report it.')
+
subdir, _ = self.environment.wrap_resolver.resolve(subp_name)
subprojects_dir = os.path.join(subdir, 'subprojects')
self.environment.wrap_resolver.load_and_merge(subprojects_dir, T.cast('SubProject', meson_depname))
diff --git a/mesonbuild/cargo/manifest.py b/mesonbuild/cargo/manifest.py
index 698bb98a5..01e7c697b 100644
--- a/mesonbuild/cargo/manifest.py
+++ b/mesonbuild/cargo/manifest.py
@@ -5,12 +5,13 @@
from __future__ import annotations
+import collections
import dataclasses
import os
import typing as T
from . import version
-from ..mesonlib import MesonException, lazy_property
+from ..mesonlib import MesonException, lazy_property, Version
from .. import mlog
if T.TYPE_CHECKING:
@@ -489,6 +490,14 @@ class CargoLockPackage:
checksum: T.Optional[str] = None
dependencies: T.List[str] = dataclasses.field(default_factory=list)
+ @lazy_property
+ def api(self) -> str:
+ return version.api(self.version)
+
+ @lazy_property
+ def subproject(self) -> str:
+ return f'{self.name}-{self.api}-rs'
+
@classmethod
def from_raw(cls, raw: raw.CargoLockPackage) -> CargoLockPackage:
return _raw_to_dataclass(raw, cls, 'Cargo.lock package')
@@ -508,3 +517,15 @@ class CargoLock:
def from_raw(cls, raw: raw.CargoLock) -> CargoLock:
return _raw_to_dataclass(raw, cls, 'Cargo.lock',
package=lambda x: [CargoLockPackage.from_raw(p) for p in x])
+
+ def named(self, name: str) -> T.Sequence[CargoLockPackage]:
+ return self._versions[name]
+
+ @lazy_property
+ def _versions(self) -> T.Dict[str, T.List[CargoLockPackage]]:
+ versions = collections.defaultdict(list)
+ for pkg in self.package:
+ versions[pkg.name].append(pkg)
+ for pkg_versions in versions.values():
+ pkg_versions.sort(reverse=True, key=lambda pkg: Version(pkg.version))
+ return versions