Correct snapcraft syntax for Rust-based snap on core22

I’m updating a core18 snap to core22. One of the parts is Rust-based, and in the original version the following was sufficient to get it built.

  xxx:
    plugin: rust
    source: .

With a core22 base this fails with the error:

Environment validation failed for part 'xxx': 'cargo' not found and part 'xxx' does not depend on a part named 'rust-deps' that would satisfy the dependency.

I don’t get the part about rust-deps, but the cargo dependency part is clear, also based on (micro) Howto migrate from core20 to core22. Adding

build-packages: [cargo, rustc]

to the part definition seems to allow the build to start, but it promptly fails with

Executing parts lifecycle: build xxx
[18/Jul/2022:16:40:52 +0000] "CONNECT crates.io:443 HTTP/1.1" 200 78517 "-" "cargo 1.59.0"
[18/Jul/2022:16:40:52 +0000] "CONNECT crates.io:443 HTTP/1.1" 200 8644 "-" "cargo 1.59.0"
[18/Jul/2022:16:40:52 +0000] "CONNECT static.crates.io:443 HTTP/1.1" 200 10253797 "-" "cargo 1.59.0"
[18/Jul/2022:16:40:52 +0000] "CONNECT github.com:443 HTTP/1.1" 200 81731880 "-" "git/1.0 (git2-curl 0.14.1)"

Failed to run the build script for part 'xxx'.                                  
Full execution log: '/root/.cache/snapcraft/log/snapcraft-20220718-164025.781575.log'                                                                          
Build failed

The above is from the CI builder. I was able to reproduce this locally, and it appears that my snap is being built with the stable Rust toolchain. The build fails because the code itself is dependent on nightly features. I do have a rust-toolchain.toml file that states

[toolchain]
channel = "nightly"

and this was being correctly picked up and built with the core18 base, but appears to be getting ignored now. This is all with snapcraft version 7.0.11.

Any tips on where I go from here?

My original message was a little roundabout, since I wrote it in the process of trying to get things to work. But I suppose ultimately the main issue I’m facing is this: the toolchain file is getting ignored. This previously worked as documented at The rust plugin, but from what I can tell that no longer seems to be so (either because of updated base, or snapcraft version, or both). In what way do I need to change the definition for this part in order to have the toolchain file be respected/use the nightly toolchain?

Actually I’m not quite sure what was happening, but this is now building successfully when I run snapcraft locally. Still erroring out on the CI builder though…seems that I need to try and find a way to access that “full execution log” after all.

Thought I’d continue following up on this (and course-correcting) in the hope that illumination finally comes in some form.

I did actually manage to reproduce the failing build locally. It seems that what made it work was the fact that I’d also (manually) installed rust via rustup. So that version of rust was evidently being used to build my snap, and behaved correctly.

But uninstalling that version and only relying on the cargo+rustc packages that are installed as build dependencies by snapcraft leads to incorrect behavior. I.e. the nightly toolchain which is required isn’t being used. Instead the stable toolchain is used and the build fails.

So maybe my next step should be to see if I can override the build and install Rust via rustup, rather than pulling in dependencies from the repo?

After some back-and-forth, the following seems to work:

  rust-deps:
    plugin: nil
    build-packages:
      - curl
    override-pull: |
      curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
  xxx:
    plugin: rust
    source: .
    after: [rust-deps]
    build-packages:
      - pkg-config

You may not need pkg-config, but in my case without it the cargo build process wasn’t able to pull in some libraries required by specific crates.

With the above approach anything in rust-toolchain.toml also appears to be respected. An alternative (but I guess less elegant) approach with respect to using a specific toolchain is to install it/set it as default during the override-pull step of rust-deps.