From 1f68a7006b864274a535b3092f92c8638d1c5e61 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 28 Nov 2025 17:29:31 +0100 Subject: [PATCH 1/2] cargo: unify call to PackageDefinition.from_values Signed-off-by: Paolo Bonzini --- mesonbuild/cargo/interpreter.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py index 25a1b70dbf01..06076fa6942b 100644 --- a/mesonbuild/cargo/interpreter.py +++ b/mesonbuild/cargo/interpreter.py @@ -831,26 +831,29 @@ def load_cargo_lock(filename: str, subproject_dir: str) -> T.Optional[CargoLock] checksum = cargolock.metadata[f'checksum {package.name} {package.version} ({package.source})'] url = f'https://crates.io/api/v1/crates/{package.name}/{package.version}/download' directory = f'{package.name}-{package.version}' - if directory not in wraps: - wraps[directory] = PackageDefinition.from_values(meson_depname, subproject_dir, 'file', { - 'directory': directory, - 'source_url': url, - 'source_filename': f'{directory}.tar.gz', - 'source_hash': checksum, - 'method': 'cargo', - }) - wraps[directory].add_provided_dep(meson_depname) + name = meson_depname + cfg = { + 'directory': directory, + 'source_url': url, + 'source_filename': f'{directory}.tar.gz', + 'source_hash': checksum, + 'method': 'cargo', + } elif package.source.startswith('git+'): url, revision, directory = _parse_git_url(package.source) - if directory not in wraps: - wraps[directory] = PackageDefinition.from_values(directory, subproject_dir, 'git', { - 'url': url, - 'revision': revision, - 'method': 'cargo', - }) + name = directory + cfg = { + 'url': url, + 'revision': revision, + 'method': 'cargo', + } wraps[directory].add_provided_dep(meson_depname) else: mlog.warning(f'Unsupported source URL in {filename}: {package.source}') + continue + if directory not in wraps: + wraps[directory] = PackageDefinition.from_values(name, subproject_dir, 'file', cfg) + wraps[directory].add_provided_dep(meson_depname) cargolock.wraps = {w.name: w for w in wraps.values()} return cargolock return None From a4b2908f071e595b71573c129b3bc532903f543b Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 28 Nov 2025 17:51:46 +0100 Subject: [PATCH 2/2] cargo: autodetect patch directory Many crates that have a build.rs will usually require an overlay with the translated meson/meson.build file. To avoid having to create a .wrap file, when parsing Cargo.lock autodetect a directory in subproject/packagefiles/ and add it as the patch_directory. Signed-off-by: Paolo Bonzini --- docs/markdown/Wrap-dependency-system-manual.md | 10 +++++++--- mesonbuild/cargo/interpreter.py | 8 ++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/markdown/Wrap-dependency-system-manual.md b/docs/markdown/Wrap-dependency-system-manual.md index 077535a8db4d..4a7250d3bca4 100644 --- a/docs/markdown/Wrap-dependency-system-manual.md +++ b/docs/markdown/Wrap-dependency-system-manual.md @@ -364,9 +364,13 @@ Some naming conventions need to be respected: - The `features` variable is pre-defined and contains the list of features enabled on this crate. -Since *1.5.0* Cargo wraps can also be provided with `Cargo.lock` file at the root -of (sub)project source tree. Meson will automatically load that file and convert -it into a series of wraps definitions. +Since *1.5.0* Cargo wraps can also be provided with `Cargo.lock` file at the +root of (sub)project source tree. Meson will automatically load that file, looking +for crates found on `crates.io` or in a git repository, and will convert those +crates into a series of wraps definitions. Since *1.11.0* the overlay directory +(`patch_directory`) is automatically detected, using the same directory as the +dependency name for `crates.io` URLs, and the final component of the URL +(possibly with the `.git` suffix removed) for "git" URLs. Since *1.10.0* Workspace Cargo.toml are supported. For the time being it is recommended to regroup all Cargo dependencies inside a single workspace invoked diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py index 06076fa6942b..e26298641c75 100644 --- a/mesonbuild/cargo/interpreter.py +++ b/mesonbuild/cargo/interpreter.py @@ -819,6 +819,7 @@ def load_cargo_lock(filename: str, subproject_dir: str) -> T.Optional[CargoLock] toml = load_toml(filename) raw_cargolock = T.cast('raw.CargoLock', toml) cargolock = CargoLock.from_raw(raw_cargolock) + packagefiles_dir = os.path.join(subproject_dir, 'packagefiles') wraps: T.Dict[str, PackageDefinition] = {} for package in cargolock.package: meson_depname = _dependency_name(package.name, version.api(package.version)) @@ -832,6 +833,7 @@ def load_cargo_lock(filename: str, subproject_dir: str) -> T.Optional[CargoLock] url = f'https://crates.io/api/v1/crates/{package.name}/{package.version}/download' directory = f'{package.name}-{package.version}' name = meson_depname + wrap_type = 'file' cfg = { 'directory': directory, 'source_url': url, @@ -842,17 +844,19 @@ def load_cargo_lock(filename: str, subproject_dir: str) -> T.Optional[CargoLock] elif package.source.startswith('git+'): url, revision, directory = _parse_git_url(package.source) name = directory + wrap_type = 'git' cfg = { 'url': url, 'revision': revision, 'method': 'cargo', } - wraps[directory].add_provided_dep(meson_depname) else: mlog.warning(f'Unsupported source URL in {filename}: {package.source}') continue + if os.path.isdir(os.path.join(packagefiles_dir, name)): + cfg['patch_directory'] = name if directory not in wraps: - wraps[directory] = PackageDefinition.from_values(name, subproject_dir, 'file', cfg) + wraps[directory] = PackageDefinition.from_values(name, subproject_dir, wrap_type, cfg) wraps[directory].add_provided_dep(meson_depname) cargolock.wraps = {w.name: w for w in wraps.values()} return cargolock