I imagine it won’t be too long before Cargo is used to build rustc itself - the advantages of doing so will become greater and greater over time, as both the libraries available via crates.io become more attractive, and as the Rust compiler infrastructure matures, it may become desirable to for non-rustc projects to independently fetch and use different versions of compiler helper libraries. (It’s easy to imagine an external tool would want to use, say, libsyntax, and also want to use Cargo’s version management to track it.) Over time, I can imagine that Cargo will become the preferred way to build Rust code, including the Rust compiler itself.
This is likely to make bootstrapping Rust on a new platform into a much bigger challenge than it has been so far. Much worse, I think, than it is currently, when we can get Rust working first, and then worry about building the package manager. There has already been a lot of complaining about the difficulty in tracking Cargo on FreeBSD (which has thankfully gotten quite a bit easier as the language has started to stabilize). I know there aren’t that many platforms to support these days, but isn’t it a pain to keep up with all our target platforms already?
And to what end? Rust is going to be the best tool for a lot of jobs for which C and C++ are currently the best tools. But it isn’t the best tool for all jobs. I so far haven’t figured out a compelling reason to believe the language is better suited to package management than, say, Ruby is. Can anyone enlighten me? To me, a scripting language seems like a better fit for Cargo’s task than Rust is. In particular:
- That scripting languages are in plain-text means that, if Cargo doesn’t work on your platform for some reason, you can hack the scripts to make it work. You can insert debugging print-statements to see what’s going on. There is a level of transparency and hackability that cannot be matched by a compiled program.
- A scripting-language Cargo would likely rely more on external tools to operate, rather than being library driven. (For example, it would likely just run
gitfrom the command-line, rather than link against
libgit2.) This would greatly improve the transparency into what Cargo is doing, and why it’s doing it, and probably stabilize Cargo quite a bit, too (command-line arguments seem to have breaking changes much more rarely than library interfaces do). This would, of course, have performance implications, but:
- It’s highly unlikely that the bottleneck in a big project build would be Cargo. It’s much more likely to be I/O as packages are downloaded from the net, and CPU when those packages actually get built. We don’t need to optimize the package manager for efficiency in the same way as we do most Rust applications.
- It should help Cargo’s portability, since it could rely more directly on OS vendors’ package managers for things like
curl, rather than having to roll our own adapters to the host platform.
- Finally, it will make it much to build tools like
rustdocusing Cargo, if we can avoid a circular dependency between Cargo and the compiler itself.
I don’t yet understand why Cargo is implemented in Rust, other than perhaps a desire to exploit the language to support its own ecosystem. It still strikes me as quite possible that Cargo in Rust will become an issue some day? (Actually, it’s already been an issue for a long time, witness the occasional FreeBSD griping about keeping up with Cargo builds. I expect this is dieing down quite a bit now, but it did show that these concerns can be a significant headache.)
I expect this may be a can of worms… I’d like to be persuaded that there’s a good reason that it’s better for Cargo to be implemented in Rust than in, say, Ruby? But I just can’t convince myself.