What exactly is a Rust "toolchain"? - rust

I've seen rustup be referred to as a "toolchain installer", but it's hard to find an exact definition of what Rust considers a "toolchain" to be and what the scope is for the concept.
I already have the Rust compiler and Cargo installed. What more does rustup bring? Is it just a Rust-version-switcher?
As a .NET-developer, maybe there is there a parallel which makes it easier for me to grasp this concept?

A toolchain is a specific version of the collection of programs needed to compile a Rust application. It includes, but is not limited to:
The compiler, rustc
The dependency manager and build tool, cargo
The documentation generator, rustdoc
The static and/or dynamic libraries comprising the standard library for the default platform
There are additional components that can be installed, such as
Documentation
The Rust Programming Language
The standard library
Various books and references
The static and/or dynamic libraries comprising the standard library for additional platforms to cross-compile to
The source code for the standard library
Extra utilities
Code formatting via rustfmt
Extra lints via clippy
Undefined behavior checking via miri
Advanced editor support via rust-analyzer or the Rust Language Server
Rustup provides ways to install, remove, update, select and otherwise manage these toolchains and their associated pieces.
See also:
How to install a Rust target for a specific rustup toolchain?
How to remove Rust compiler toolchains with Rustup?
How to switch between rust toolchains
How do I tell which Windows toolchain my Rust compiler is using?
How to execute cargo test using the nightly channel?

Related

error: linker `x86_64-w64-mingw32-gcc` not found

I am using MacOS Big Sur, and i am trying to cross compile to windows, but the problem is, this "error: linker x86_64-w64-mingw32-gcc not found" prevents me from doing that, here are my cargo dependencies:
[dependencies]
rand = "0.8.4"
macroquad = "0.3.13"
perlin_rust = "0.1.0"
libm = "0.2.2"
I have tried Cargo Clean/Update, and I have tried mvsc instead of gnu
TLDR;
Besides installing a cross target with rustup you need to install an actual cross linker and tell cargo about it using cargo config file or an environment variable
It seems you are attempting to cross compile your package.
you can read here more about cross compilation;
In a nutshell compiler is a program that takes your text source code and produces something the your operating system and cpu can understand.
When you are building software for the platform you are developing on, it's all nice. You have all the tools but when you want to target another platform or os, you need a compiler that is produced to work on your machine but outputs a binary that is supposed to work on the target platform/os.
So, In your case you need to install a cross toolchain that for mac for mingw target because rust does not have a cross linker itself. Once you get a cross toolchain all you need to do is to tell cargo how to find it.
Here is a project aims to make cross compilation less painful.
I also strongly advise you to read the cargo book
here you can see one of the ways of telling cargo about the cross linker
another way is to use an environment variable (which I like better and easier to use with makefiles)
and below you can see an example of that from one of my makefiles
and Again the cargo book refers to it
Overall cross compiling is painful it took me quite some time to understand the mechanics of it but it was worth it instead of copy pasting commands I found on the blogs.
I also feel like it lacks severe documentation. Cargo book doesn't tell you anything about finding a linker assumes you know this already and pictures cross compiling as something just work out of box after installing a target toolchain with rustup.
I had the same problem, the reason was that there were special characters in the directory where I had the project. such as accents á, í, etc.
So I changed them for regular characters and the problem stopped showing.

cargo version: What doest the -nightly suffix mean?

I've built a rust toolchain using someone else's repo, and it contains
a configure line I'm not familiar with: --release-channel=nightly
After I build and install the toolchain it reports its version as:
rustc 1.57.0-nightly (f1edd0429 2021-11-29)
while the standard off the shelf install of 1.57 reports its version as:
rustc 1.57.0 (f1edd0429 2021-11-29)
What does the nightly suffix mean in this version string?
Nightly is an unstable, unfinished, experimental version of Rust.
The name comes from the fact that literally every night a new "nightly" version is automatically released from whatever happens to be in the rust-lang repository at the time.
The nightly version allows use of Rust features that are still work in progress, special unstable features that are private to the compiler or the standard library, or even features that were failed experiments and will never be available in the stable releases of the Rust language.
Nightly versions may crash, may miscompile code, may stop working at any time. There is absolutely no warranty about them. Do not use them unless you specifically want to test the latest, unfinished Rust language features.
There's one case where users may hear about "nightly" features: when they use an outdated version of the compiler.
When an old Rust version sees language features "from the future", it may ask you to enable nightly features to use the code. This is misleading. You should upgrade Rust to the latest stable version instead of using nightly.

What is the exact difference between a Crate and a Package?

I come from a Java background and have recently started with Rust.
The official Rust doc is pretty self-explanatory except the chapter that explains Crates and Packages.
The official doc complicates it with so many ORs and ANDs while explaining the two.
This reddit post explains it a little better, but is not thorough.
What is the exact difference between a Crate and Package in Rust? Where/When do we use them?
Much thanks!
Crates
From the perspective of the Rust compiler, "crate" is the name of the compilation unit. A crate consists of an hierarchy of modules in one or multiple files. This is in contrast to most "traditional" compiled languages like Java, C or C++, where the compilation unit is a single file.
From the perspective of an user, this definition isn't really helpful. Indeed, in most cases, you will need to distinguish between two types of crates:
binary crates can be compiled to executables by the Rust compiler. For example, Cargo, the Rust package manager, is a binary crate translated by the Rust compiler to the executable that you use to manage your project.
library crates are what you'd simply call libraries in other languages. A binary crate can depend on library crates to use functionality supplied by the libraries.
Packages
The concept of packages does not originate in the Rust compiler, but in Cargo, the Rust package manager. At least for simple projects, a package is also what you will check into version control.
A package consists of one or multiple crates, but no more than one library crate.
Creating packages
to create a new package consisting of one binary crate, you can run cargo new
to create a new package consisting of one library crate, you can run cargo new --lib
to create a package consisting of a library as well as one or multiple binaries, you can run either cargo new or cargo new --lib and then modify the package directory structure to add the other crate
When should you use crates, and when should you use packages?
As you can see now, this question doesn't really make sense – you should and must always use both. A package can't exist without at least one crate, and a crate is (at least if you are using Cargo) always part of a package.
Therefore, a better question is this:
When should you put multiple crates into one package?
There are multiple reasons to have more than one crate in a package. For example:
If you have a binary crate, it is idiomatic to have the "business logic" in a library in the same package. This has multiple advantages:
Libraries can be integration tested while binaries can't
If you later decide that the business logic needs to also be used in another binary, it is trivial to add this second binary to the package and also use the library
If you have a library crate that generates some files (a database engine or something like that), you may want to have a helper binary to inspect those files
Note that if you have a very big project, you may instead want to use the workspace feature of Cargo in these cases.

Dealing with dependencies of cargo crates

I am new to Rust, so excuse me if im just doing things horribly wrong.
While larning the language i wanted to try out different bindings of libraries that i already used in other languages, amongst them SDL2, SFML2, Gtk3.
To my surprise, nothing seemed to work out of the box. They all depend on C libraries and those don't come with the cargo crate. I managed to get SFML2 to work after following the readme and manually copying .lib and .dll files to the right places. I tried to make the Rust linker to look into my vcpk directory for .lib files, sadly with no success.
The whole point of a package manager kind of is to automate these things for you. Other package managers like NuGet for C# dont require you to manually fiddle the dependencies for their packages together.
Getting rid of the thirdparty library management hell of C/C++ was one of the reasons why i took a closer look at Rust.
Am i doing something wrong, or is this just how things are with Rust/Cargo?
Cargo is a build management and source package management tool for Rust code - it is not a tool for managing binaries or compiling other languages such as C or C++.
Having said that, it is a very flexible tool so it is possible for crates that provide bindings to libraries written in other languages to "bundle" the libraries they depend on.
The Rust-SDL2 crate, for example, does offer such a feature - as it says in their README:
Since 0.31, this crate supports a feature named "bundled" which
downloads SDL2 from source, compiles it and links it automatically.
To use this, you would would add it to your Cargo.toml like this:
[dependancies]
sdl2 = { version = "0.34.0", features=["bundled"] }
Not all such binding crates support bundling, especially if the libraries they bind to are large, complex, have lots of their own dependencies and/or have lots of compile time configuration options.
In those cases you will either need to install a pre-compiled binary, or compile them from source yourself.

Why does `cargo new` create a binary instead of a library?

I am creating a library with Rust. On library creation I type
cargo new name
According to the docs this should create a lib, because --bin is omitted.
However, the file is auto set to a binary.
Is there a setting I have to adjust to disable auto setting all projects to binary?
Cargo features
Cargo’s CLI has one really important change this release: cargo new will now default to generating a binary, rather than a library. We try to keep Cargo’s CLI quite stable, but this change is important, and is unlikely to cause breakage.
For some background, cargo new accepts two flags: --lib, for creating libraries, and --bin, for creating binaries, or executables. If you don’t pass one of these flags, in previous versions of Cargo, it would default to --lib. We made this decision because each binary (often) depends on many libraries, and so the library case is more common. However, this is incorrect; each library is depended upon by many binaries. Furthermore, when getting started, what you often want is a program you can run and play around with. It’s not just new Rustaceans though; even very long-time community members have said that they find this default surprising. As such, we’re changing it.
Source
Since Cargo 1.25 cargo new defaults to creating a binary crate, instead of a library crate.
cargo new accepts two flags: --lib, for creating libraries, and --bin, for creating binaries, or executables.
See the Changelog for 1.25.

Resources