Skip to content

Instantly share code, notes, and snippets.

@MaulingMonkey
Last active October 18, 2020 18:49
Show Gist options
  • Save MaulingMonkey/88c964b3e5e36ec228bfa5fce9d42f29 to your computer and use it in GitHub Desktop.
Save MaulingMonkey/88c964b3e5e36ec228bfa5fce9d42f29 to your computer and use it in GitHub Desktop.
Wrapping Cargo

Premise

I'm authoring a set of build tools / yet another cargo subcommand for creating packages. Prior art includes cargo-apk, cargo-deb, cargo-web, wasm-pack, etc. I'd like to generate temporary Cargo.toml packages as well, which has less prior art.

Example: Windows Wrapper

Would generate:

  • main.rs specifying #![windows_subsystem=...] and a stub main
  • build.rs invoking winres, natvis-pdbs, etc.
  • Cargo.toml with [dev-dependencies]

Example: Android Wrapper

Would generate:

  • Cargo.toml with crate-type = ["cdylib"]
  • lib.rs with multiple #![no_mangle] entry points for Java to call into

The problem

Cargo.lock. If these generated Cargo.toml files add dependencies, things get hairy real fast.

Option 1: Second workspace for the wrappers

This leads to two lockfiles, which is super awkward - will likely lead to building the same crates twice with slightly different dependencies. Also, rustc source paths are workspace relative and thus awkward with the generated workspace.

  • /Cargo.toml
  • /Cargo.lock
  • /.generated/Cargo.toml
  • /.generated/Cargo.lock

Option 2: Workspace only for the wrappers

This leads to poor intellisense since it doesn't know anything about my wrapping tool, also poor paths for errors:

  • /Wrapper.toml
  • /.generated/Cargo.toml
  • /.generated/Cargo.lock

Option 3: Workspace only for the wrappers, in the root?

  • /Wrapper.toml
  • /Cargo.toml - this could be added to .gitignore as well?
    Could be checked for an autogenerated # DO NOT EDIT THIS FILE intro comment?
  • /Cargo.lock

Option 4: Edit workspace temporarilly on-disk

What happens on Ctrl+C? Explosions?

  • /Cargo.toml
  • /Cargo.lock

Build process would be:

  • copy /Cargo.toml -> /Cargo.toml.orig
  • edit /Cargo.toml
  • ...build commands...
  • copy /Cargo.toml.orig -> /Cargo.toml

Option 5: Extend Cargo.toml in-memory

Would use e.g. cargo::core::WorkspaceRootConfig to add the original workspace packages, and the generated packages, to an in-memory workspace.

  • cargo update might still remove stuff from Cargo.lock
  • cargo is an expensive dependency

Option 6: Invoke rustc directly, no generated Cargo.toml s

  • Makes using build.rs-friendly crates like winres and natvis-pdbs which output directly to stdout annoying (embed them into the subcommand, fork/self-invoke and capture output, then pase & pipe that into rustc?)
  • Synthesizing the same flags cargo would use is difficult/annoying/brittle
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment