Skip to content
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

cargo vendor pull large amounts of unrelated crates. #11929

Closed
WhyNotHugo opened this issue Apr 3, 2023 · 14 comments
Closed

cargo vendor pull large amounts of unrelated crates. #11929

WhyNotHugo opened this issue Apr 3, 2023 · 14 comments
Labels

Comments

@WhyNotHugo
Copy link

Problem

When I run cargo vendor, it downloads a huge amount of crates that are not dependencies for my codebase. The total size of the vendor directory is 230M, but the unnecessary dependencies are over 182M (slightly over 80%).

cargo tree confirms that none of these are [transitive] dependencies for my project.

Most of these seem to be winapi and its subtree of dependencies. However, my code has nothing windows-related, and probably won't even run on windows. I suspect, however, that cargo by default assumes that it does, and that some transitive dependency depends on one of these (Although I'm not sure why cargo tree won't list them).

Steps

  1. git clone https://git.sr.ht/~whynothugo/shotman
  2. cd shotman
  3. cargo vendor

Possible Solution(s)

Does cargo has a way of determining on which targets my code actually builds? This would be the ideal approach so it can just ignore unnecessary dependencies. I don't think my code would build on windows, since it uses some basic things like file-descriptors and other Unix-only features.

Otherwise, being able to explicitly specify "this won't build on windows" would be useful to avoid downloading all the dependencies that are specific for that target.

Notes

Since cargo tree doesn't list these crates as dependencies, there's also no obvious way for me to even figure out where they're coming from.

Version

> cargo version --verbose
cargo 1.68.2
release: 1.68.2
host: x86_64-alpine-linux-musl
libgit2: 1.5.0 (sys:0.16.0 vendored)
libcurl: 8.0.1 (sys:0.4.59+curl-7.86.0 system ssl:OpenSSL/3.1.0)
os: Alpine Linux 3.18_alpha20230208 [64-bit]
@WhyNotHugo WhyNotHugo added the C-bug Category: bug label Apr 3, 2023
@epage
Copy link
Contributor

epage commented Apr 3, 2023

Related: #7058

@WhyNotHugo
Copy link
Author

Good reference, thanks. They're slightly difference scenarios, but hopefully a common fix can address both.

@WhyNotHugo
Copy link
Author

Any ideas how to make these show up in cargo tree?

@epage
Copy link
Contributor

epage commented Apr 3, 2023

I wasn't sure, so I ran cargo tree -h

 --target <TRIPLE>       Filter dependencies matching the given target-triple (default host platform). Pass `all` to include all targets.

Looks like --target all will show it for you

@WhyNotHugo
Copy link
Author

Thanks!

@WhyNotHugo
Copy link
Author

It seems that if all my top-level dependencies are defined as [target.'cfg(unix)'.dependencies], transitive dependencies which are marked as [target.'cfg(windows)'.dependencies] as still included in the cargo tree and cargo vendor.

@weihanglo
Copy link
Member

Going to close this as a duplicate of #7058. They seem best to be discussed as a whole. Let us know if this is wrong and we can consider reopen.

@weihanglo weihanglo closed this as not planned Won't fix, can't repro, duplicate, stale Apr 11, 2023
@WhyNotHugo
Copy link
Author

Sure, hopefully a common solution will fix both issues.

@eslerm
Copy link

eslerm commented Dec 17, 2023

hi @weihanglo o/

I believe this issue is broader than single platform vendored packages, like #7058.

If you make a simple hello world package with a dependency to clap, running cargo vendor will pull in a bunch of dependencies for clap that the hello world base package won't actually use.

This issue seems to be described on https://wiki.ubuntu.com/RustCodeInMain

It’s a simple matter of running cargo vendor where your on the top-level directory. Sadly, it’s not possible to exclude irrelevant dependencies during vendoring yet, so you might want to automate that step and add some post-processing to remove voluminous, unused dependencies, and/or the C code for some system libraries that could be statically linked.

Possibly an AST could determine which dependencies the base package actually uses, to debloat vendored packages.

@weihanglo
Copy link
Member

@eslerm
Cargo knows nothing about Rust AST, so this is out of the scope of Cargo right now.

@eslerm
Copy link

eslerm commented Feb 22, 2024

@weihanglo could this issue please be re-opened as unresolved?

I understand that this feature might not be added. By having an accurate issue, distros with vendored rust packages can be pointed here 🙏

@epage
Copy link
Contributor

epage commented Feb 22, 2024

They can still be pointed here.

Re-opening miscommunicates our intent with the community and makes it harder to track our backlog.

@WhyNotHugo
Copy link
Author

WhyNotHugo commented Feb 22, 2024 via email

@eslerm
Copy link

eslerm commented Feb 22, 2024

Thanks everyone.

#7058 has a narrower scope and doesn't fully overlap with this one, but resolving it would help immensely. (A lot of bandwidth is being spent vendoring unnecessary Windows crates for Linux software.)

My hunch is that a secondary tool will be needed to lint the results of cargo vendor.

A colleague pointed out that an AST would be complicated, as different cfg() parameters would need to be accounted for and that projects might need to be patched to use resolver = "2" so that cargo won't look at cfg-outed dependencies. There's a related discussion about this that I'll edit into this comment when I find it.

edit: https://poignardazur.github.io/2021/02/15/rust-wishlist-better-cfg/

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

No branches or pull requests

4 participants