Skip to content

Multiple binaries/shared library project structure best practice #8362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
oeed opened this issue Apr 6, 2021 · 5 comments
Closed

Multiple binaries/shared library project structure best practice #8362

oeed opened this issue Apr 6, 2021 · 5 comments

Comments

@oeed
Copy link
Contributor

oeed commented Apr 6, 2021

I'm encountering bad performance penalties from what is presumably a bad project file structure.

I have a monorepo containing multiple binaries performing unrelated tasks with a lib folder with a bunch of crates these binaries use (each uses some but not all crates) and these lib crates have dependencies between themselves.

Here's a rough guide to the file structure:

binary_a/
  Cargo.toml
  src/...

binary_b/
  Cargo.toml
  src/...

lib/
  lib_a/
    Cargo.toml
    src/...

  lib_b/
    Cargo.toml
    src/...

A binary's Cargo.toml looks somewhat like:

[package]
name = "binary_a"

[dependencies]
lib_a = {path = "../lib/lib_a"}

and a library's:

[package]
name = "lib_a"

[dependencies]
lib_b = {path = "../lib/lib_b"}

I then have VSCode workspace for each binary that includes the binary and the lib folder:

{
  "folders": [{
      "path": "."
    },
    {
      "path": "../lib"
    }
  ]
}

However, this seems to spin up a cargo check for every single crate in lib the binary is using and becomes almost unusably performance draining. It also seems to duplicate indexing/checking external dependencies (i.e. serde is indexed N times).

Screen Shot 2021-04-06 at 2 59 10 PM

I had previously use a root Cargo workspace which included every binary and library. The performance was better, although it still did two cargo checks, but editing multiple binaries at once (hence two VSCode workspaces) didn't really work as one would have a lock and the other wouldn't.

Opening just the binary folder sees much better performance but then I can easily access files in lib which is where 90% of the code is. I've tried finding a way to disable the plugin on just the lib folder but it doesn't seem possible.


What's the best structure to use here? I feel like I'm definitely doing something wrong, so I'm quite happy to completely rearrange everything if required. Thanks!

@bjorn3
Copy link
Member

bjorn3 commented Apr 6, 2021

You can use a cargo workspace. This will also share the target dir used by cargo for all crates. To make a cargo workspace add a file Cargo.toml in the root of the project with a content like:

[workspace]
include = ["binary_a", "binary_b", "lib/lib_a", "lib/lib_b"]

@oeed
Copy link
Contributor Author

oeed commented Apr 6, 2021

Yes I'd used that method for a while, the problem is when you have multiple binaries open at once there's only one Cargo lock and so only one window seems to check at a time.

@bjorn3
Copy link
Member

bjorn3 commented Apr 7, 2021

Rust analyzer doesn't support sharing the server instance between multiple editor instances, so one way or another if you use multiple vscode windows, rust analyzer will run multiple times.

@oeed
Copy link
Contributor Author

oeed commented Apr 7, 2021

Perhaps I'm not explaining my situation clearly, apologies.

  • Without a Cargo workspace VSCode is spinning up over a dozen instances of RA per window (see screenshot, one per path dep it seems).
  • With a Cargo workspace there is only a single lock, so multiple VSCode instances don't work.

Is there another alternative?

@oeed
Copy link
Contributor Author

oeed commented Apr 13, 2021

For anyone else with a similar issue, I've found setting the 'linked projects' setting solves this. My assumption is rather by specifying just one Cargo.toml RA won't automatically run an instance for each Cargo.toml.

Thus, specify something like the following:

    "rust-analyzer.linkedProjects": [
        "../binary_a/Cargo.toml"
    ]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants