I'm new to Rust and I just created a new project via cargo new my_project
. I noticed that cargo offers these two command-line options:
I gather that the latter can be used to compile any project on my machine, while the former can only be used within the current working directory. Is that correct? Are there any other differences? Running both commands with no additional arguments gives me the exact same output.
Cargo is Rust's build system and package manager. Most Rustaceans use this tool to manage their Rust projects because Cargo handles a lot of tasks for you, such as building your code, downloading the libraries your code depends on, and building those libraries.
rustc is the compiler for the Rust programming language, provided by the project itself. Compilers take your source code and produce binary code, either as a library or executable. Most Rust programmers don't invoke rustc directly, but instead do it through Cargo.
A build script is a file that is started by a build plan. The build script prepares output from generated files.
Cargo stores the output of a build into the "target" directory. By default, this is the directory named target in the root of your workspace. To change the location, you can set the CARGO_TARGET_DIR environment variable, the build. target-dir config value, or the --target-dir command-line flag.
To get a good grasp of how the commands differ on a high level, we can compare the implementation of the commands. So we'll first clone the cargo
repo with
git clone https://github.com/rust-lang/cargo.git
and then compare the implementations of cargo build
and cargo rustc
with
diff -u -w cargo/src/bin/cargo/commands/build.rs cargo/src/bin/cargo/commands/rustc.rs
From this, it is easy to see that both cargo build
and cargo rustc
are thin wrappers around this internal cargo function:
pub fn compile<'a>(ws: &Workspace<'a>, options: &CompileOptions) -> CargoResult<Compilation<'a>> {
// ...
}
but with differences in what kind of options that are exposed. In fact, one can read this comment at the top of cargo_compile.rs
that defines that function:
//! This module contains the entry point for starting the compilation process
//! for commands like `build`, `test`, `doc`, `rustc`, etc.
In other words, cargo build
and cargo rustc
are not the only thin wrappers around the same compilation entry point.
So, why would the people behind cargo choose to do this? Why not have a single cargo compile
command with tons of flags that fully exposes the underlying implementation?
It clearly must be a matter of organizing things in a way that is both easy to document and understand for various target audiences of the Rust ecosystem.
Most newcomers to the Rust ecosystem is not going to want to be exposed to the possibility of tweaking compiler flags, for example. So it makes sense to only expose them to cargo build
and its documentation in the beginning, with its particular flavor of compilation options.
Once they become more advanced users, they'll discover that they can get a lot more detailed influence over the compilation process with cargo rustc
.
There is no difference with respect to the working directory. The difference is in how you can pass compiler options to rustc
, many of which Cargo does not know about/expose:
cargo build [OPTIONS]
: If you want to pass a flag to rustc
, generally you cannot do that on the command line, you need to use the RUSTFLAGS variable or edit config files.
cargo rustc [OPTIONS] [-- ARGS]
: The OPTIONS
available are more or less the same as for cargo build
, but the args are passed to rustc
. So you can for instance write cargo rustc --release -- -C overflow-checks=yes
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With