Rust

From Gentoo Wiki
Jump to:navigation Jump to:search

Rust is a general-purpose, multi-paradigm, compiled, programming language.

Installation

USE flags

USE flags for dev-lang/rust Systems programming language originally developed by Mozilla

+system-llvm Use the system LLVM installation
big-endian Big-endian toolchain support
clippy Install clippy, Rust code linter
debug Enable extra debug codepaths, like asserts and extra output. If you want to get meaningful backtraces see https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Backtraces
dist Install dist tarballs (used for bootstrapping)
doc Add extra documentation (API, Javadoc, etc). It is recommended to enable per package instead of globally
llvm-libunwind Use llvm-runtimes/libunwind instead of sys-libs/libunwind
lto Enable Link-Time Optimization (LTO) to optimize the build
miri Install miri, an interpreter for Rust's mid-level intermediate representation (requires USE=nightly, sometimes is broken)
mrustc-bootstrap Use dev-lang/mrustc to build the bootstrap Rust sysroot from this package's source
nightly Enable nightly (UNSTABLE) features (NOTE: it does not install nightly version, just enables features marked as nightly at time of release)
parallel-compiler Build a multi-threaded rustc (experimental, not tested by upstream)
rust-analyzer Install rust-analyzer, A Rust compiler front-end for IDEs (language server)
rust-src Install rust-src, needed by developer tools and for build-std (cross)
rustfmt Install rustfmt, Rust code formatter
test Enable dependencies and/or preparations necessary to run tests (usually controlled by FEATURES=test but can be toggled independently)
verify-sig Verify upstream signatures on distfiles
wasm Build support for the wasm32-unknown-unknown target

USE flags for dev-lang/rust-bin Systems programming language from Mozilla

big-endian Big-endian toolchain support
clippy Install clippy, Rust code linter
doc Add extra documentation (API, Javadoc, etc). It is recommended to enable per package instead of globally
prefix Defines if a Gentoo Prefix offset installation is used
rust-analyzer Install rust-analyzer, A Rust compiler front-end for IDEs (language server)
rust-src Install rust-src, needed by developer tools and for build-std (cross)
rustfmt Install rustfmt, Rust code formatter
verify-sig Verify upstream signatures on distfiles

Emerge

Tip
Rust is a relatively large compile. Unless there is a specific reason to prefer the from-source build (such as the need for non default USE flags), consider selecting dev-lang/rust-bin.

Emerge the package:

root #emerge --ask dev-lang/rust

Alternatively, emerge the binary package:

root #emerge --ask dev-lang/rust-bin

Rust Channels

Rust is released to three different "channels": stable, beta, and nightly. The stable releases are made every 6 weeks (with occasional point releases). Beta releases are the version that will appear in the next stable release. Nightly releases are made every night.

-- The Rustup book

Stable

The stable channel is the latest versioned release of Rust. These ebuilds are always keyworded for supported arches and will eventually be stabilised, provided that no major issues are encountered. The stable channel is typically used on Gentoo systems for package dependencies.

Gentoo developers build dev-lang/rust-bin for niche architectures so this package is often a good choice.

Beta

Gentoo packages the beta channel for each dev-lang/rust and dev-lang/rust-bin release. The beta channel is not keyworded, but is not particularly unsafe to use as the only development on this channel is fixing regressions. Users that need to build nightly dev-lang/rust will need this channel first (though portage will handle this via package dependencies).

Users who would like to take advantage of prerelease language features and who are willing to report any bugs encountered may consider using this channel.

If installed the beta channel Rust may be selected by portage as the appropriate dependency for system packages.

Nightly

Tip
No ebuilds in the Gentoo tree require nightly Rust.

Any packages that require nightly features at compile-time will enable them via the RUSTC_BOOTSTRAP variable.
Tip
If nightly Rust fails to compile, try fetching the latest beta or nightly snapshot and building with that. See ERUST_SLOT_OVERRIDE and ERUST_TYPE_OVERRIDE in rust.eclass for some pointers.

As per advice from upstream, it is best practice to only enable nightly builds on either bleeding-edge git checkouts or nightly tarball snapshots. As such, and to better reflect the 'unstable' features enabled by nightly build type, the nightly USE flag will shortly be disappearing from versioned releases. Users desiring nightly Rust should instead unmask and install the live ebuilds. These are available for dev-lang/rust and dev-lang/rust-bin.

The live ebuild for dev-lang/rust has a large initial git checkout, however deltas should be relatively small for subsequent checkouts; consider dev-lang/rust-bin if this is a concern.

Users that would like (or have some reason) to run bleeding-edge Rust may emerge these ebuilds. There are no stability guarantees (although the dev-lang/rust-bin snapshots are theoretically safer than an arbitrary git checkout), and portage will select nightly Rust if it is available and suitable (i.e. there's no maximum Rust version set) for the package. hic sunt dracones; you have been warned.

Why dev-lang/rust depends on dev-lang/rust-bin

The Rust compiler is self-hosting, that is, Rust is used to build Rust. Very early versions of the Rust compiler were written in OCaml, and it is still possible to bootstrap Rust this way; doing so requires building many, many versions of Rust. This method is not supported on Gentoo and would likely involve bootstrapping an appropriate OCaml first.

Since Rust is required to build Rust, some method of breaking this circular dependency is required. Legacy Gentoo Rust packaging (in the absence of system-bootstrap) would always download an appropriate binary Rust release and use that to bootstrap the Rust compiler in the release tarball. Modern Gentoo Rust packaging makes this requirement more explicit by depending on appropriate versions of dev-lang/rust and dev-lang/rust-bin to ensure that a suitable Rust is available at build-time.

It is currently possible to bootstrap Rust entirely from source (on amd64) using dev-lang/mrustc via dev-lang/rust[mrustc-bootstrap]; this requires building all intermediate slots until a desired version is reached.

Users on legacy Rust packaging poor world file hygiene may encounter blockers due to this change. They can normally be resolved by deselecting Rust entirely:

root #emerge --deselect dev-lang/rust dev-lang/rust-bin virtual/rust

If this does not resolve the issue, try reaching out for help on IRC in #gentoo (webchat).

Distcc MAKEOPTS

Rust does not support distcc compiling, however it is possible to use a binary host to fill this role. Binary_package_guide#Advanced_topics

If a user still wishes to use distcc for some unknown reason, it may require a local package.env defined to avoid excessive I/O consumption when building on distcc tuned hosts (i.e. MAKEOPTS="-j30 -l4", 30 is greater than 4 local CPU cores).

--local-load is not honored, so an appropriate --jobs value in relation to the locally available build resources must be passed:

FILE /etc/portage/env/makeopts.conf
MAKEOPTS="-jN"
FILE /etc/portage/package.env/rust
dev-lang/rust makeopts.conf

Configuration

Environment variables

RUSTFLAGS is an environment variable that Cargo[1], the Rust package manager[2], gives rustc, the Rust compiler[3], space-separated "codegen" -C flags[4]. Here are example settings, not including model specific parallelism[5], for /etc/portage/make.conf:

FILE /etc/portage/make.conf
# target-cpu=native is the equivalent of -march=native in C/CXXFLAGS:
RUSTFLAGS="-C target-cpu=native"
# enable target-cpu=native and DT_RELR
RUSTFLAGS="-C target-cpu=native -C link-arg=-Wl,-z,pack-relative-relocs"

Link Time Optimization (LTO)

LTO in Rust programs should only be enabled on LLVM/CLANG compiler based systems, please see the LTO article for more information.

Optimization level

There is no need in specifying:

FILE /etc/portage/make.conf
RUSTFLAGS="-C opt-level=3"

explicitly, because official Rust documentation[6] states that default optimization level on Release profile is set to 3 already.

Eselect Rust

Tip
eselect-rust does not have any impact on the version of Rust that Portage selects to build software.

There is an eselect available to switch between different Rust slots. Usage in the usual way, get a numbered list of installed Rust versions with:

user $eselect rust list

Set the version of rust with the number x via:

user $eselect rust set x

Rustup

Note
Portage supports slotted Rust installations; it is typically easier to unmask the specific slot and ask Portage to emerge it than to try and implement Rustup on a Gentoo system. eselect-rust can be used to trivially switch the Rust implementation on-the-fly, or the appropriate version can be prefixed into a user's PATH without administrative access.

Rustup can be used to setup a cargo-compatible environment for Rust development. First, install the package:

root #emerge --ask dev-util/rustup

Then, use rustup-init-gentoo to symlink the system rust installation to the local user's home directory:

user $rustup-init-gentoo --symlink
'/home/larry/.cargo/bin/rustc' -> '/usr/bin/rustup-init'
'/home/larry/.cargo/bin/rustdoc' -> '/usr/bin/rustup-init'
'/home/larry/.cargo/bin/cargo' -> '/usr/bin/rustup-init'
'/home/larry/.cargo/bin/rust-lldb' -> '/usr/bin/rustup-init'
'/home/larry/.cargo/bin/rust-gdb' -> '/usr/bin/rustup-init'
'/home/larry/.cargo/bin/rust-gdbgui' -> '/usr/bin/rustup-init'
'/home/larry/.cargo/bin/rls' -> '/usr/bin/rustup-init'
'/home/larry/.cargo/bin/cargo-clippy' -> '/usr/bin/rustup-init'
'/home/larry/.cargo/bin/clippy-driver' -> '/usr/bin/rustup-init'
'/home/larry/.cargo/bin/cargo-miri' -> '/usr/bin/rustup-init'
'/home/larry/.cargo/bin/rust-analyzer' -> '/usr/bin/rustup-init'
'/home/larry/.cargo/bin/rustfmt' -> '/usr/bin/rustup-init'
'/home/larry/.cargo/bin/cargo-fmt' -> '/usr/bin/rustup-init'
'/home/larry/.cargo/bin/rustup' -> '/usr/bin/rustup-init'
* Setting gentoo rust-1.77.1 as default toolchain
rustup 1.27.0 (2024-03-24)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
verbose: read metadata version: '12'
verbose: creating toolchains directory: '/home/larry/.rustup/toolchains'
verbose: installing toolchain 'gentoo'
verbose: toolchain directory: '/home/larry/.rustup/toolchains/gentoo'
verbose: linking directory from: '/home/larry/.rustup/toolchains/gentoo'
verbose: toolchain 'gentoo' installed
verbose: read metadata version: '12'
info: default toolchain set to 'gentoo'
Default host: x86_64-unknown-linux-gnu
rustup home:  /home/larry/.rustup

gentoo (default)
rustc 1.77.1 (7cf61ebde 2024-03-27) (gentoo)
* Prepend /home/larry/.cargo/bin to your PATH to use rustup
* rustup selfupdate is disabled, it will be updated by portage

Alternatively, you can use rustup-init to install rust separately in your home directory, isolated from the system's rust installation. This may be necessary for tools that require a local user installation, for example the esp-rs toolchain. You will need to add your local installation's rust binaries to your PATH such that they override the system's binaries, like so:

FILE ~/.config/localrust.shOverriding system rust using a script
export PATH="${HOME}/.cargo/bin:${PATH}"

It might be desirable to add this script as an alias in your .bashrc, so you can use the system installation of rust by default, and switch to your local environment by running localrust:

FILE ~/.bashrcAdding alias in bashrc
alias localrust=". ~/.config/localrust.sh"

Usage

Development

While the purpose of Gentoo's Rust package is mainly to provide a build environment to emerge other packages that use Rust, it is still possible to develop in Rust with this package. The Rust compiler, rustc, is installed and available as soon as the package is emerged. However, there are certain other things to consider when developing in Rust.

In a generic installation of Rust (one that is not done with Gentoo's Rust package) things are usually updated and installed with dev-util/rustup.

Another way is to install another Rust for development separately with the instructions from the Rust documentation.

Language servers

For code autocompletion and highlighting, two language servers are available in the Rust universe: Rust-analyzer and the Rust Language Server.

As of today RLS is deprecated and now longer maintained. But it still comes with the Rust package when the rls USE flag is enabled. Rust-analyzer was merged into the Rust language and is now part of Rust since version 1.64.0. Rust-analyzer can be installed with the enabled USE flag rust-analyzer for dev-lang/rust (or dev-lang/rust-bin).

In order for the language server to autosuggest code from the Rust standard library dev-lang/rust or dev-lang/rust-bin[rust-src] is required.

Code formatting

Rust comes with its own built in code formatter, rustfmt. To use rustfmt, emerge dev-lang/rust[rustfmt] (or dev-lang/rust-bin[rustfmt]). Code formatting is invoked in a project directory via cargo fmt.

Code linting

Rust also comes with an officially supported code linter called Clippy. To make Clippy available, emerge dev-lang/rust[clippy] or dev-lang/rust-bin[clippy]).

Rust vs other programming languages

Rust vs. C++

Both Rust and C++ are powerful programming languages, but they have distinct features and design principles that set them apart. Rust provides a more modern and safe alternative to C++. It prioritizes memory safety through its ownership, borrowing, and lifetimes system, effectively preventing common memory-related bugs.[2] Rust's expressive syntax aims for readability and maintainability, and it offers built-in safety features that help mitigate programming mistakes. While Rust's ecosystem of libraries may not be as extensive as C++ yet, it is rapidly growing and being actively developed. Rust is gaining in popularity [3], particularly in projects that emphasize security, reliability, and parallelism.

On the other hand, C++ provides a long-standing, versatile language with extensive libraries and a mature toolchain, making it a popular choice for a wide range of applications. [4] It offers developers low-level control and direct hardware manipulation, making it suitable for resource-constrained environments and performance-critical applications. [5] Additionally, C++ benefits from a larger ecosystem and a bigger pool of experienced developers and a wealth of existing codebases, which can facilitate code reuse and finding expertise. [6]

The choice between C++ and Rust ultimately depends on the specific project requirements. If low-level control and direct hardware manipulation are essential, C++ may be the preferred choice. However, for projects where memory safety and modern language features are crucial, Rust offers a safer alternative without sacrificing performance. Factors such as the level of control needed, the importance of safety, and the availability of expertise and codebases should be considered when making a decision between these two languages.

See also

  • Application level package management — provides best practice recommendations on managing the coexistence of operating system and application level package managers on Gentoo.
  • Assembly language — the lowest level of all programming languages, typically represented as a series of CPU architecture specific mnemonics and related operands.
  • C — a programming language developed for Bell Labs in the early 1970s
  • C++ — a general-purpose programming language that originated from C
  • Clang — a C/C++/Objective-C/C++, CUDA, and RenderScript language front-end for the LLVM project
  • Forth — a heavily stack-oriented self-compiling procedural programming language that is only slightly more abstract than assembly.
  • WD-40 — a feature in Gentoo profiles to disable Rust being built on the system

References

  1. The Rust Project Developers. Environment Variables Retrieved on June 16, 2024.
  2. The Rust Project Developers. The Cargo Book Retrieved on June 16, 2024.
  3. The Rust Project Developers. The rustc Book Retrieved on June 16, 2024.
  4. The Rust Project Developers. Codegen Options Retrieved on June 16, 2024.
  5. The Rust SIMD Performance Guide Contributors. Rust SIMD Performance Guide Retrieved on October 28, 2024.
  6. Rust Docs [1]