Introduction to Rust
The Rust programming language is
designed to be a safe, concurrent, practical language.
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 GLFS 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 GLFS 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 2GB DRAM
per core) that might be an alternative to taking CPUs offline.
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 GLFS 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.
Rust Dependencies
Required
CMake-3.31.0 and cURL-8.11.0
Note
An Internet connection is needed for building this package.
Recommended
libssh2,
LLVM-19.1.0 (built with -DLLVM_LINK_LLVM_DYLIB=ON
so that rust can link to system LLVM instead of building its
shipped version), and SQLite
Note
If a recommended dependency is not installed, a shipped copy in
the Rustc source tarball will be built and used.
Note
This may take a while to build. Feel free to do something else
while this is building.
Installation of Rust
Note
Currently the rust compiler produces SSE2 instructions for 32-bit
x86, causing the generated code to be broken on 32-bit systems
without a SSE2-capable processor. All x86 processor models
released after 2004 should be SSE2-capable. Run lscpu | grep sse2 as a test. If
it outputs anything, your CPU is SSE2-capable and OK. Otherwise
you may try to build this package on a
SSE2-capable system with the following fix applied:
sed 's@pentium4@pentiumpro@' -i \
compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs
And copy the resulting /opt/rustc-1.82.0
to the system without SSE2
capability. But this change is still under upstream review and
not tested by GLFS editors.
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 > config.toml << "EOF" &&
# see config.toml.example for more possible options.
# 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]
EOF
if [ ! -f /usr/lib32/libc.so.6 ]; then
cat >> config.toml << "EOF"
targets = "X86"
EOF
fi &&
cat >> config.toml << "EOF" &&
# When using system llvm prefer shared libraries
link-shared = true
EOF
if [ -f /usr/lib32/libc.so.6 ]; then
cat >> config.toml << "EOF"
[build]
target = [
"x86_64-unknown-linux-gnu",
"i686-unknown-linux-gnu",
]
EOF
fi &&
cat >> config.toml << "EOF" &&
# 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 GLFS #154e"
# Uncomment if FileCheck has been installed.
#codegen-tests = false
# Enable the same optimizations as the official upstream build.
lto = "thin"
codegen-units = 1
EOF
if [ -f /usr/lib32/libc.so.6 ]; then
cat >> config.toml << "EOF"
[target.x86_64-unknown-linux-gnu]
cc = "/usr/bin/gcc"
cxx = "/usr/bin/g++"
ar = "/usr/bin/gcc-ar"
ranlib = "/usr/bin/gcc-ranlib"
llvm-config = "/usr/bin/llvm-config"
[target.i686-unknown-linux-gnu]
cc = "/usr/bin/gcc"
cxx = "/usr/bin/g++"
ar = "/usr/bin/gcc-ar"
ranlib = "/usr/bin/gcc-ranlib"
EOF
else
cat >> config.toml << "EOF"
[target.x86_64-unknown-linux-gnu]
llvm-config = "/usr/bin/llvm-config"
[target.i686-unknown-linux-gnu]
llvm-config = "/usr/bin/llvm-config"
EOF
fi
Note
The above commands will create config.toml differently depending
on if a few checks pass/fail. This was done to avoid confusion.
Note
The python3 x.py
commands may output a warning message complaining “no
codegen-backends config matched the requested path to build a
codegen backend
”. And the provided
“suggestion” (add backend to codegen-backends in
config.toml
) will not silence it. This warning is
bogus and
it should be ignored.
Compile Rust by running the
following commands:
python3 x.py build
Now, as the root
user, install the
package:
python3 x.py install rustc std &&
python3 x.py install --stage=1 cargo clippy rustfmt
Still as the root
user, fix the
installation of the documentation and 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
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 = [...]
: this builds the
targets that will be necessary for NVK from Mesa-24.2.7.
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.
Configuring Rust
Configuration
Information
If you installed rustc in
/opt
, you need to update the
following configuration files so that rustc is correctly found by other packages
and system processes.
Create the /etc/profile.d/rustc.sh
startup file as the root
user:
cat > /etc/profile.d/rustc.sh << "EOF"
# Begin /etc/profile.d/rustc.sh
pathprepend /opt/rustc/bin PATH
# End /etc/profile.d/rustc.sh
EOF
Immediately after installation, update the current PATH for your
current shell:
source /etc/profile.d/rustc.sh