Introduction to Rust
The Rust programming language is
designed to be a safe, concurrent, practical language.
This package is updated on a six-weekly release cycle. Because it
is such a large and slow package to build, is at the moment only
required by a few packages in this book, and particularly because
newer versions tend to break older mozilla packages, the BLFS
editors take the view that it should only be updated when that is
necessary (either to fix problems, or to allow a new version of a
package to build).
As with many other programming languages, rustc (the rust compiler)
needs a binary from which to bootstrap. It will download a stage0
binary at the start of the build, so you cannot compile it without
an Internet connection.
Note
Although BLFS usually installs in /usr
, when you later upgrade to a newer version
of rust the old libraries in
/usr/lib/rustlib
will remain, with
various hashes in their names, but will not be usable and will
waste space. The editors recommend placing the files in the
/opt
directory. In particular, if
you have reason to rebuild with a modified configuration (e.g.
using the shipped LLVM after building with shared LLVM, perhaps
to compile crates for architectures which the BLFS LLVM build
does not support) it is possible for the install to leave a
broken cargo
program. In such a situation, either remove the existing
installation first, or use a different prefix such as
/opt/rustc-1.82.0-build2.
If you prefer, you can of course change the prefix to
/usr
.
The current rustbuild build-system
will use all processors, although it does not scale well and often
falls back to just using one core while waiting for a library to
compile. However it can be mostly limited to a specified number of
processors by a combination of adding the switch --jobs <N>
(e.g. '--jobs 4' to limit to 4
processors) on each invocation of python3 x.py and using an environment variable
CARGO_BUILD_JOBS=<N>
. At the
moment this is not effective when some of the rustc tests are run.
The current version of rust's num_cpus crate now recognizes that
cgroups can be used to restrict which processors it is allowed to
use. So if your machine lacks DRAM (typically, less than 2 GB DRAM
per core) that might be an alternative to taking CPUs offline. Read
the section
called “Use Linux Control Group to Limit the Resource Usage”
for how to use a cgroup.
At the moment Rust does not
provide any guarantees of a stable ABI.
Note
Rustc defaults to building for ALL supported architectures, using
a shipped copy of LLVM. In BLFS the build is only for the X86
architecture. If you intend to develop rust crates, this build
may not be good enough for your purposes.
The build times of this version when repeated on the same machine
are often reasonably consistent, but as with all compilations
using rustc there
can be some very slow outliers.
Note
Development versions of BLFS may not build or run some packages
properly if LFS or dependencies have been updated since the most
recent stable versions of the books.
Package Information
-
Download (HTTP): https://static.rust-lang.org/dist/rustc-1.82.0-src.tar.xz
-
Download MD5 sum: 8d6a14f1c8d0ab03dffbc81f7a839aa7
-
Download size: 210 MB
-
Estimated disk space required: 8.9 GB (298 MB installed); add
6.4 GB if running the tests
-
Estimated build time: 6.7 SBU (including download time; add
6.2 SBU for tests, both using parallelism=8)
Rust Dependencies
Required
CMake-3.31.1 and cURL-8.11.0
Note
An Internet connection is needed for building this package.
Recommended
libssh2-1.11.1, LLVM-19.1.0 (built with -D
LLVM_LINK_LLVM_DYLIB=ON so that rust can link to system LLVM
instead of building its shipped version), and SQLite-3.47.1
Note
If a recommended dependency is not installed, a shipped copy in
the Rustc source tarball will be built and used.
Optional
GDB-15.2 (used
by the test suite if it is present), git-2.47.1 (required by the test
suite), cranelift,
jemalloc,
libgccjit (read command explanation in GCC-14.2.0), and libgit2
Editor Notes: https://wiki.linuxfromscratch.org/blfs/wiki/rust
Installation of Rust
To install into the /opt
directory,
remove any existing /opt/rustc
symlink and create a new directory (i.e. with a different name if
trying a modified build of the same version). As the root
user:
mkdir -pv /opt/rustc-1.82.0 &&
ln -svfn rustc-1.82.0 /opt/rustc
Note
If multiple versions of Rust are
installed in /opt
, changing to
another version only requires changing the /opt/rustc
symbolic link and then running
ldconfig.
Create a suitable config.toml
file
which will configure the build.
cat << EOF > config.toml
# see config.toml.example for more possible options
# See the 8.4 book for an old example using shipped LLVM
# e.g. if not installing clang, or using a version before 13.0
# Tell x.py the editors have reviewed the content of this file
# and updated it to follow the major changes of the building system,
# so x.py will not warn us to do such a review.
change-id = 129295
[llvm]
# by default, rust will build for a myriad of architectures
targets = "X86"
# When using system llvm prefer shared libraries
link-shared = true
[build]
# omit docs to save time and space (default is to build them)
docs = false
# install extended tools: cargo, clippy, etc
extended = true
# Do not query new versions of dependencies online.
locked-deps = true
# Specify which extended tools (those from the default install).
tools = ["cargo", "clippy", "rustdoc", "rustfmt"]
# Use the source code shipped in the tarball for the dependencies.
# The combination of this and the "locked-deps" entry avoids downloading
# many crates from Internet, and makes the Rustc build more stable.
vendor = true
[install]
prefix = "/opt/rustc-1.82.0"
docdir = "share/doc/rustc-1.82.0"
[rust]
channel = "stable"
description = "for BLFS r12.2-743"
# Enable the same optimizations as the official upstream build.
lto = "thin"
codegen-units = 1
[target.x86_64-unknown-linux-gnu]
# NB the output of llvm-config (i.e. help options) may be
# dumped to the screen when config.toml is parsed.
llvm-config = "/usr/bin/llvm-config"
[target.i686-unknown-linux-gnu]
# NB the output of llvm-config (i.e. help options) may be
# dumped to the screen when config.toml is parsed.
llvm-config = "/usr/bin/llvm-config"
EOF
Now remove some tests triggering a full rebuild of the Rust
standard library and compiler, remove a special case for supporting
the cargo test suite
(that we don't run because it's expected to be running in a Rustc
git repository) but triggering a rebuild of cargo when running python3 x.py install, and prevent
building one component useless for BLFS:
sed '/MirOpt/d' -i src/bootstrap/src/core/builder.rs &&
sed 's/!path.ends_with("cargo")/true/' \
-i src/bootstrap/src/core/build_steps/tool.rs &&
sed 's/^.*build_wasm.*$/#[allow(unreachable_code)]&return false;/' \
-i src/bootstrap/src/lib.rs
Compile Rust by running the
following commands:
[ ! -e /usr/include/libssh2.h ] || export LIBSSH2_SYS_USE_PKG_CONFIG=1
[ ! -e /usr/include/sqlite3.h ] || export LIBSQLITE3_SYS_USE_PKG_CONFIG=1
python3 x.py build
Note
The test suite will generate some messages in the systemd journal for traps on invalid opcodes, and
for segmentation faults. In themselves these are nothing to worry
about, just a way for the test to be terminated.
To run the tests (again using all available CPUs) issue:
python3 x.py test --verbose --no-fail-fast | tee rustc-testlog
Four tests in the tests/run-make
directory are known to fail because they need targets not enabled
in the BLFS LLVM-19.1.0 configuration (nor the llvm.targets
in config.toml
, in case building with the shipped
LLVM). One test named core::config::tests::download_ci_llvm
is known to
fail. And, one test named 121444.rs
is known to fail with LLVM 19.1 or newer because a crash is fixed
with the new LLVM but the Rustc test harness does not have the
concept of unexpected passes.
As with all large test suites, some tests might fail on some
machines - if the number of additional failures is low, check the
log for 'failures:' and review lines above that, particularly the
'stderr:' lines. Any mention of SIGSEGV or signal 11 in a failing
test is a cause for concern.
If you get any other failing
test which reports an issue number then you should search for that
issue. For example, when rustc >= 1.41.1 was built with a
version of sysllvm before 10.0 the test for issue 69225 failed
https://github.com/rust-lang/rust/issues/69225
and that should be regarded as a critical failure (they released
1.41.1 because of it). Most other failures will not be critical.
Therefore, you should determine the number of failures. The number
of tests which passed and failed can be found by running:
grep '^test result:' rustc-testlog |
awk '{sum1 += $4; sum2 += $6} END { print sum1 " passed; " sum2 " failed" }'
The other available fields are $8 for those which were ignored
(i.e. skipped), $10 for 'measured' and $12 for 'filtered out' but
both those last two are probably zero.
Now, as the root
user, install the
package:
Note
If sudo or
su is invoked for
switching to the root
user,
ensure LIBSSH2_SYS_USE_PKG_CONFIG
and
LIBSQLITE3_SYS_USE_PKG_CONFIG
are
correctly passed or the following command may rebuild
cargo with shipped
copies of libssh2 and sqlite. For sudo, use the --preserve-env=LIB{SSH2,SQLITE3}_SYS_USE_PKG_CONFIG
option. For su, do
not use the -
or --login
options.
python3 x.py install rustc std &&
python3 x.py install --stage=1 cargo clippy rustfmt
Still as the root
user, fix the
installation of documentation, symlink a Zsh completion file into the correct location,
and move a Bash completion file
into the location recommended by the Bash completion maintainers:
rm -fv /opt/rustc-1.82.0/share/doc/rustc-1.82.0/*.old &&
install -vm644 README.md \
/opt/rustc-1.82.0/share/doc/rustc-1.82.0 &&
install -vdm755 /usr/share/zsh/site-functions &&
ln -sfv /opt/rustc/share/zsh/site-functions/_cargo \
/usr/share/zsh/site-functions
mv -v /etc/bash_completion.d/cargo /usr/share/bash-completion/completions
Finally, unset the exported environment variables:
unset LIB{SSH2,SQLITE3}_SYS_USE_PKG_CONFIG
Command Explanations
ln -svfn rustc-1.82.0
/opt/rustc: if this is not the first use of the
/opt/rustc
symlink, overwrite it by
forcing, and use the '-n' flag to avoid getting confusing results
from e.g. ls -l.
targets = "X86"
: this avoids building
all the available linux cross-compilers (AArch64, MIPS, PowerPC,
SystemZ, etc). Unfortunately, rust insists on installing source
files for these below /opt/rustc/lib/src
.
extended = true
: this installs several
tools (specified by the tools
entry)
alongside rustc.
tools = ["cargo", "clippy", "rustdoc",
"rustfmt"]
: only build the tools from the 'default' profile
in binary command rustup which are recommended for
most users. The other tools are unlikely to be useful unless using
(old) code analyzers or editing the standard library.
channel = "stable"
: this ensures only
stable features can be used, the default in config.toml
is to use development features, which
is not appropriate for a released version.
[target.x86_64-unknown-linux-gnu]
: the
syntax of config.toml
requires an
llvm-config
entry for each target for
which system-llvm is to be used. Change the target to [target.i686-unknown-linux-gnu]
if you are
building on 32-bit x86. This whole section may be omitted if you
wish to build against the shipped llvm, or do not have clang, but
the resulting build will be larger and take longer.
export
LIBSSH2_SYS_USE_PKG_CONFIG=1: Allow cargo to link to system libssh2.
export
LIBSQLITE3_SYS_USE_PKG_CONFIG=1: Allow cargo to link to system sqlite.
--verbose
: this switch can
sometimes provide more information about a test which fails.
--no-fail-fast
: this switch
ensures that the test suite will not stop at the first error.
--stage=1
: this switch
works around an issue causing some Rustc components unnecessarily
rebuilt running python3 x.py
install.