- Frequently Asked Questions
- Is the plan to use GitHub as a package repository?
- Why build crates.io rather than use GitHub as a registry?
- Will Cargo work with C code (or other languages)?
- Can Cargo be used inside of make (or ninja, or …)
- Does Cargo handle multi-platform packages or cross-compilation?
- Does Cargo support environments, like production or test?
- Does Cargo work on Windows?
- Why do binaries have Cargo.lock in version control, but not libraries?
- Can libraries use * as a version for their dependencies?
- Why Cargo.toml?
- How can Cargo work offline?
Frequently Asked Questions
Is the plan to use GitHub as a package repository?
No. The plan for Cargo is to use crates.io, like npm or Rubygems do withnpmjs.org and rubygems.org.
We plan to support git repositories as a source of packages forever,because they can be used for early development and temporary patches,even when people use the registry as the primary source of packages.
Why build crates.io rather than use GitHub as a registry?
We think that it’s very important to support multiple ways to downloadpackages, including downloading from GitHub and copying packages intoyour package itself.
That said, we think that crates.io offers a number of important benefits, andwill likely become the primary way that people download packages in Cargo.
For precedent, both Node.js’s npm and Ruby’s bundler support both acentral registry model as well as a Git-based model, and most packagesare downloaded through the registry in those ecosystems, with animportant minority of packages making use of git-based packages.
Some of the advantages that make a central registry popular in otherlanguages include:
- Discoverability. A central registry provides an easy place to lookfor existing packages. Combined with tagging, this also makes itpossible for a registry to provide ecosystem-wide information, such as alist of the most popular or most-depended-on packages.
- Speed. A central registry makes it possible to easily fetch justthe metadata for packages quickly and efficiently, and then toefficiently download just the published package, and not other bloatthat happens to exist in the repository. This adds up to a significantimprovement in the speed of dependency resolution and fetching. Asdependency graphs scale up, downloading all of the git repositories bogsdown fast. Also remember that not everybody has a high-speed,low-latency Internet connection.
Will Cargo work with C code (or other languages)?
Yes!
Cargo handles compiling Rust code, but we know that many Rust packageslink against C code. We also know that there are decades of toolingbuilt up around compiling languages other than Rust.
Our solution: Cargo allows a package to specify a script(written in Rust) to run before invoking rustc
. Rust is leveraged toimplement platform-specific configuration and refactor out common buildfunctionality among packages.
Can Cargo be used inside of make (or ninja, or …)
Indeed. While we intend Cargo to be useful as a standalone way tocompile Rust packages at the top-level, we know that some people willwant to invoke Cargo from other build tools.
We have designed Cargo to work well in those contexts, paying attentionto things like error codes and machine-readable output modes. We stillhave some work to do on those fronts, but using Cargo in the context ofconventional scripts is something we designed for from the beginning andwill continue to prioritize.
Does Cargo handle multi-platform packages or cross-compilation?
Rust itself provides facilities for configuring sections of code basedon the platform. Cargo also supports platform-specificdependencies, and we plan to support more per-platformconfiguration in Cargo.toml
in the future.
In the longer-term, we’re looking at ways to conveniently cross-compilepackages using Cargo.
Does Cargo support environments, like production or test?
We support environments through the use of profiles to support:
- environment-specific flags (like
-g —opt-level=0
for developmentand—opt-level=3
for production). - environment-specific dependencies (like
hamcrest
for test assertions). - environment-specific
#[cfg]
- a
cargo test
command
Does Cargo work on Windows?
Yes!
All commits to Cargo are required to pass the local test suite on Windows.If, however, you find a Windows issue, we consider it a bug, so please file anissue.
Why do binaries have Cargo.lock in version control, but not libraries?
The purpose of a Cargo.lock
is to describe the state of the world at the timeof a successful build. It is then used to provide deterministic builds acrosswhatever machine is building the package by ensuring that the exact samedependencies are being compiled.
This property is most desirable from applications and packages which are at thevery end of the dependency chain (binaries). As a result, it is recommended thatall binaries check in their Cargo.lock
.
For libraries the situation is somewhat different. A library is not only used bythe library developers, but also any downstream consumers of the library. Usersdependent on the library will not inspect the library’s Cargo.lock
(even if itexists). This is precisely because a library should not be deterministicallyrecompiled for all users of the library.
If a library ends up being used transitively by several dependencies, it’slikely that just a single copy of the library is desired (based on semvercompatibility). If Cargo used all of the dependencies' Cargo.lock
files,then multiple copies of the library could be used, and perhaps even a versionconflict.
In other words, libraries specify semver requirements for their dependencies butcannot see the full picture. Only end products like binaries have a fullpicture to decide what versions of dependencies should be used.
Can libraries use * as a version for their dependencies?
As of January 22nd, 2016, crates.io rejects all packages (not just libraries)with wildcard dependency constraints.
While libraries can, strictly speaking, they should not. A version requirementof *
says “This will work with every version ever,” which is never goingto be true. Libraries should always specify the range that they do work with,even if it’s something as general as “every 1.x.y version.”
Why Cargo.toml?
As one of the most frequent interactions with Cargo, the question of why theconfiguration file is named Cargo.toml
arises from time to time. The leadingcapital-C
was chosen to ensure that the manifest was grouped with othersimilar configuration files in directory listings. Sorting files often putscapital letters before lowercase letters, ensuring files like Makefile
andCargo.toml
are placed together. The trailing .toml
was chosen to emphasizethe fact that the file is in the TOML configurationformat.
Cargo does not allow other names such as cargo.toml
or Cargofile
toemphasize the ease of how a Cargo repository can be identified. An option ofmany possible names has historically led to confusion where one case was handledbut others were accidentally forgotten.
How can Cargo work offline?
Cargo is often used in situations with limited or no network access such asairplanes, CI environments, or embedded in large production deployments. Usersare often surprised when Cargo attempts to fetch resources from the network, andhence the request for Cargo to work offline comes up frequently.
Cargo, at its heart, will not attempt to access the network unless told to doso. That is, if no crates comes from crates.io, a git repository, or some othernetwork location, Cargo will never attempt to make a network connection. As aresult, if Cargo attempts to touch the network, then it's because it needs tofetch a required resource.
Cargo is also quite aggressive about caching information to minimize the amountof network activity. It will guarantee, for example, that if cargo build
(oran equivalent) is run to completion then the next cargo build
is guaranteed tonot touch the network so long as Cargo.toml
has not been modified in themeantime. This avoidance of the network boils down to a Cargo.lock
existingand a populated cache of the crates reflected in the lock file. If either ofthese components are missing, then they're required for the build to succeed andmust be fetched remotely.
As of Rust 1.11.0 Cargo understands a new flag, —frozen
, which is anassertion that it shouldn't touch the network. When passed, Cargo willimmediately return an error if it would otherwise attempt a network request.The error should include contextual information about why the network request isbeing made in the first place to help debug as well. Note that this flag doesnot change the behavior of Cargo, it simply asserts that Cargo shouldn't touchthe network as a previous command has been run to ensure that network activityshouldn't be necessary.
For more information about vendoring, see documentation on sourcereplacement.