rustgstreameryoctorust-cargo

Cargo failed to load source dependency, virtual manifest


I'm new to Rust/Cargo and been struggling to address an issue when compiling a new Yocto recipe for gst-plugins-rs, the Cargo.toml file can be found in this directory structure.

../gstreamer1.0-plugins-rs/0.12.11-r0/git/
├── audio
│   ├── audiofx
│   ├── claxon
│   ├── csound
│   ├── lewton
│   └── spotify
├── Cargo.lock
├── Cargo.lock.orig
├── Cargo.toml
├── cargo_wrapper.py
├── CHANGELOG.md
|   ...
└── video
    ├── cdg
    ...
    └── webp

The Cargo.toml basically consists of the following.

[workspace]
resolver = "2"

members = [
  "audio/audiofx"
  "audio/claxon"
  ...
]

default-members = [
  "audio/audiofx"
  "audio/claxon"
  ...
]

[workspace.package]
version = "0.12.11"
repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"
edition = "2021"
rust-version = "1.70"

[workspace.dependencies]
once_cell = "1"
glib = { git = "https://github.com/gtk-rs/gtk-rs-core", branch = "0.19", version = "0.19" }
...
gtk = { package = "gtk4", git = "https://github.com/gtk-rs/gtk4-rs", branch = "0.8", version = "0.8"}
...
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "0.22", version = "0.22" }
...

Regarding the Yocto Recipe there's not much out of the ordinary, only a custom do_install that moves .so files, but it's failing in the do_compile stage. The recipe is based off this old patch request, but has been updated to more recent versions. Basically consisting of the following,

...
SRC_URI = " \
    git://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git;protocol=https;branch=0.12;name=default; \
    gitsm://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git;protocol=https;branch=0.22;name=gstreamer-rs;destsuffix=cargo_home/git/db/gstreamer-rs-79e52a2d27eb91a3 \
    git://github.com/gtk-rs/gtk-rs-core.git;protocol=https;branch=0.19;name=gtk-rs-core;destsuffix=cargo_home/git/db/gtk-rs-core-7be42ca38bd6361c \
    git://github.com/gtk-rs/gtk4-rs;protocol=https;branch=0.8;name=gtk4-rs;destsuffix=cargo_home/git/db/gtk4-rs-e74ad56283dfeb5e \
    git://github.com/rust-av/ffv1.git;protocol=https;branch=master;name=ffv1;destsuffix=cargo_home/git/db/ffv1-08f2e3b26709fb34 \
    git://github.com/rust-av/flavors;protocol=https;branch=master;name=flavors;destsuffix=cargo_home/git/db/flavors-0f978a4d88ad8592 \
    crate://crates.io/adler/1.0.2 \
    crate://crates.io/adler32/1.2.0 \
    crate://crates.io/aes/0.8.4 \
    crate://crates.io/aho-corasick/1.1.3 \
    ...

inherit cargo pkgconfig

DEPENDS = " \
    gstreamer1.0 \
    gstreamer1.0-plugins-good \
"
...

The error I'm receiving is the following,

cargo build -v --frozen --target aarch64-lmp-linux-gnu --release --manifest-path=.../gstreamer1.0-plugins-rs/0.12.11-r0/git//Cargo.toml
NOTE: cargo build -v --frozen --target aarch64-lmp-linux-gnu --release --manifest-path=.../gstreamer1.0-plugins-rs/0.12.11-r0/git//Cargo.toml 
error: failed to load source for dependency `gtk4-rs`

Caused by:
  Unable to update .../gstreamer1.0-plugins-rs/0.12.11-r0/cargo_home/git/db/gtk4-rs-e74ad56283dfeb5e

Caused by:
  found a virtual manifest at `.../gstreamer1.0-plugins-rs/0.12.11-r0/cargo_home/git/db/gtk4-rs-e74ad56283dfeb5e/Cargo.toml` instead of a package manifest

Perhaps I need to convert gtk4-rs's Cargo.toml to a package manifest? Or is there a cargo command that needs to be changed so that it expects a virtual manifest?

Any suggestions would be much appreciated and I'm happy to share more details. Also if there are some cargo debugging commands I could run, please let me know.

I initially thought the SRC_URI, specifically the destsuffix, was the issue initially, but when removing the sources, e.g. gstreamer-rs, gtk-rs-core, etc, I've confirmed that gst-plugins-rs is looking for those other sources at those paths.


Solution

  • I’m not familiar with Yocto, so I can’t advise you on exactly how to fix this problem, but I am familiar with Cargo. Based on the build error, you seem to be trying to replace git dependencies with path dependencies.

    Cargo has a special behavior for Git dependencies, that no other dependency type has: it will search the contents of (the requested revision of) the repository for the requested package (here gtk4). So, when Cargo looks at https://github.com/gtk-rs/gtk4-rs, it searches until it finds the package manifest https://github.com/gtk-rs/gtk4-rs/blob/main/gtk4/Cargo.toml, not the workspace manifest https://github.com/gtk-rs/gtk4-rs/blob/main/Cargo.toml. (I believe the workspace manifest does not at all affect the search, but I could be wrong.)

    path dependencies have no such search behavior — the path must be to the directory containing exactly the needed package manifest. So, when you wish to transform a git dependency to a path dependency, you must find the correct package directory within the repository and use that path in the dependency.

    The reason Cargo says “found a virtual manifest” is that a virtual manifest is a manifest that does not define a package, only a workspace. For your purposes, understand the error as “no package found in this directory, but FYI, we did find something else that is not a package”. You need to point Cargo to the correct (sub)directory instead.