glfs/shareddeps/drivers/rust.xml
2024-10-19 10:00:29 -06:00

694 lines
23 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % general-entities SYSTEM "../../general.ent">
%general-entities;
<!ENTITY rust-download-http "https://static.rust-lang.org/dist/rustc-&rust-version;-src.tar.xz">
<!ENTITY rust-download-ftp " ">
<!ENTITY change-id "129295">
]>
<sect1 id="rust" xreflabel="rustc-&rust-version;">
<?dbhtml filename="rust.html"?>
<title>Rustc-&rust-version;</title>
<indexterm zone="rust">
<primary sortas="a-rust">Rust</primary>
</indexterm>
<sect2 role="package">
<title>Introduction to Rust</title>
<para>
The <application>Rust</application> programming language is designed
to be a safe, concurrent, practical language.
</para>
<para>
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.
</para>
<note>
<para>
Although GLFS usually installs in <filename
class="directory">/usr</filename>, when you later upgrade to a newer
version of <application>rust</application> the old libraries in <filename
class="directory">/usr/lib/rustlib</filename> 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 <filename
class="directory">/opt</filename> 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
<command>cargo</command> program. In such a situation, either remove
the existing installation first, or use a different prefix such as
/opt/rustc-&rust-version;-build2.
</para>
<para>
If you prefer, you can of course change the prefix to <filename
class="directory">/usr</filename>.
</para>
</note>
<para>
The current <application>rustbuild</application> 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 <literal>--jobs &lt;N&gt;</literal>
(e.g. '--jobs 4' to limit to 4 processors) on each invocation of
<command>python3 x.py</command> <emphasis>and</emphasis> using an
environment variable <envar>CARGO_BUILD_JOBS=&lt;N&gt;</envar>. At the
moment this is not effective when some of the rustc tests are run.
</para>
<para>
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.
<!--
Read <xref linkend='build-in-cgroup'/> for how to use a cgroup.
-->
</para>
<para>
At the moment <application>Rust</application> does not provide any
guarantees of a stable ABI.
</para>
<note>
<para>
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.
</para>
<para>
The build times of this version when repeated on the same machine are
often reasonably consistent, but as with all compilations using
<command>rustc</command> there can be some very slow outliers.
</para>
</note>
<itemizedlist spacing="compact">
<listitem>
<para>
Download (HTTP): <ulink url="&rust-download-http;"/>
</para>
</listitem>
<listitem>
<para>
Download (FTP): <ulink url="&rust-download-ftp;"/>
</para>
</listitem>
</itemizedlist>
<!-- only keep this here for reuse in case we need a patch
<bridgehead renderas="sect3">Additional Downloads</bridgehead>
<itemizedlist spacing="compact">
<listitem>
<para>
Optional patch (recommended if running the test suite):
<ulink url="&patch-root;/rustc-&rust-version;-testsuite_fix-1.patch"/>
</para>
</listitem>
</itemizedlist>
-->
<bridgehead renderas="sect3">Rust Dependencies</bridgehead>
<bridgehead renderas="sect4">Required</bridgehead>
<para role="required">
<xref linkend="cmake"/> and
<!-- Required for downloading stage 0 binaries.
Otherwise it's recommended (if not installed, a vendored copy
will be built). -->
<xref linkend="curl"/>
</para>
&build-use-internet;
<bridgehead renderas="sect4">Recommended</bridgehead>
<para role="recommended">
<ulink url="&blfs-svn;/general/libssh2.html">libssh2</ulink>,
<xref linkend="llvm"/>
(built with -DLLVM_LINK_LLVM_DYLIB=ON so that rust can link to
system LLVM instead of building its shipped version), and
<ulink url="&blfs-svn;/server/sqlite.html">SQLite</ulink>
</para>
<note>
<para>
If a recommended dependency is not installed, a shipped copy in the
Rustc source tarball will be built and used.
</para>
</note>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
href="../../xincludes/long-build-time.xml"/>
</sect2>
<sect2 role="installation">
<title>Installation of Rust</title>
<note>
<para>
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
<command>lscpu | grep sse2</command> as a test. If it outputs
anything, your CPU is SSE2-capable and OK. Otherwise you may try
to build this package <emphasis>on a SSE2-capable system</emphasis>
with the following fix applied:
</para>
<!-- computeroutput used deliberately to stop anyone from copying
blindly -->
<screen role="nodump"><computeroutput>sed 's@pentium4@pentiumpro@' -i \
compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs</computeroutput></screen>
<para>
And copy the resulting
<filename class="directory">/opt/rustc-&rust-version;</filename>
to the system without SSE2 capability. But this change is still
under upstream review and not tested by GLFS editors.
</para>
</note>
<para>
To install into the
<filename class="directory">/opt</filename> directory, remove any
existing <filename>/opt/rustc</filename> symlink
and create a new directory (i.e. with a different name if trying a
modified build of the same version).
As the <systemitem class="username">root</systemitem>
user:
</para>
<screen role="root"><userinput>mkdir -pv /opt/rustc-&rust-version; &amp;&amp;
ln -svfn rustc-&rust-version; /opt/rustc</userinput></screen>
<note>
<para>
If multiple versions of <application>Rust</application> are installed
in <filename class="directory">/opt</filename>, changing to another
version only requires changing the <filename> /opt/rustc</filename>
symbolic link and then running <command>ldconfig</command>.
</para>
</note>
<para>
Create a suitable <filename>config.toml</filename> file which will
configure the build.
</para>
<screen><userinput>cat &gt; config.toml &lt;&lt; "EOF"
<literal># 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 = &change-id;
[llvm]</literal>
EOF
if [ ! -f /usr/lib32/libc.so.6 ]; then
cat &gt;&gt; config.toml &lt;&lt; "EOF"
<literal>targets = "X86"
</literal>
EOF
fi
cat &gt;&gt; config.toml &lt;&lt; "EOF"
<literal># When using system llvm prefer shared libraries
link-shared = true
</literal>
EOF
if [ -f /usr/lib32/libc.so.6 ]; then
cat &gt;&gt; config.toml &lt;&lt; "EOF"
<literal>[build]
target = [
"x86_64-unknown-linux-gnu",
"i686-unknown-linux-gnu",
]
</literal>
EOF
fi
cat &gt;&gt; config.toml &lt;&lt; "EOF"
<literal># 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-&rust-version;"
docdir = "share/doc/rustc-&rust-version;"
[rust]
channel = "stable"
description = "for GLFS &version;"
# Uncomment if FileCheck has been installed.
#codegen-tests = false
# Enable the same optimizations as the official upstream build.
lto = "thin"
codegen-units = 1
</literal>
EOF
if [ -f /usr/lib32/libc.so.6 ]; then
cat &gt;&gt; config.toml &lt;&lt; "EOF"
<literal>[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"</literal>
EOF
else
cat &gt;&gt; config.toml &lt;&lt; "EOF"
<literal>[target.x86_64-unknown-linux-gnu]
llvm-config = "/usr/bin/llvm-config"
[target.i686-unknown-linux-gnu]
llvm-config = "/usr/bin/llvm-config"</literal>
EOF
fi</userinput></screen>
<note>
<para>
The above commands will create config.toml differently depending
on if a few checks pass/fail. This was done to avoid confusion.
</para>
</note>
<note>
<para>
The <command>python3 x.py</command> commands may output a warning
message complaining <quote><computeroutput>no codegen-backends
config matched the requested path to build a codegen
backend</computeroutput></quote>. And the provided
<quote>suggestion</quote> (<computeroutput>add backend to
codegen-backends in config.toml</computeroutput>) will not silence
it. This warning is <ulink
url='https://github.com/rust-lang/rust/issues/110692'>bogus</ulink>
and it should be ignored.
</para>
</note>
<para>
Compile <application>Rust</application> by running the following
commands:
</para>
<!-- fixed in 1.58.0, retain as a reminder that fixed crates can be used
<screen><userinput>sed -i -e '/^curl /s/0.4.38/0.4.40/' \
-e '/^curl-sys /s/0.4.48/0.4.50/' \
src/tools/cargo/Cargo.toml &amp;&amp; -->
<screen><userinput>python3 x.py build</userinput></screen>
<para>
Now, as the &root; user, install the package:
</para>
<screen role='root'><userinput>python3 x.py install rustc std &amp;&amp;
python3 x.py install --stage=1 cargo clippy rustfmt</userinput></screen>
<para>
Still as the &root; user, fix the installation of the documentation
and symlink a <application>Zsh</application> completion file into the
correct location and move a <application>Bash</application> completion
file into the location recommended by the <application>Bash</application>
completion maintainers:
</para>
<screen role='root'><userinput>rm -fv /opt/rustc-&rust-version;/share/doc/rustc-&rust-version;/*.old &amp;&amp;
install -vm644 README.md \
/opt/rustc-&rust-version;/share/doc/rustc-&rust-version; &amp;&amp;
install -vdm755 /usr/share/zsh/site-functions &amp;&amp;
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</userinput></screen>
</sect2>
<sect2 role="commands">
<title>Command Explanations</title>
<para>
<command>ln -svfn rustc-&rust-version; /opt/rustc</command>: if this is
not the first use of the <filename class="directory">/opt/rustc</filename>
symlink, overwrite it by forcing, and use the '-n' flag to avoid getting
confusing results from e.g. <command>ls -l</command>.
</para>
<para>
<literal>targets = [...]</literal>: this builds the targets that will
be necessary for NVK from <xref linkend="mesa"/>.
</para>
<para>
<literal>extended = true</literal>: this installs several tools
(specified by the <literal>tools</literal> entry) alongside
<command>rustc</command>.
</para>
<para>
<literal>tools = ["cargo", "clippy", "rustdoc", "rustfmt"]</literal>:
only build the tools from the 'default' profile in binary command
<command>rustup</command> which are recommended for most users.
The other tools are unlikely to be useful unless using (old) code
analyzers or editing the standard library.
</para>
<para>
<literal>channel = "stable"</literal>: this ensures only stable features
can be used, the default in <filename>config.toml</filename> is to use
development features, which is not appropriate for a released version.
</para>
<!-- comment while using shipped LLVM -->
<para>
<literal>[target.x86_64-unknown-linux-gnu]</literal>: the syntax of
<filename>config.toml</filename> requires an <literal>llvm-config</literal>
entry for each target for which system-llvm is to be used. Change the target
to <literal>[target.i686-unknown-linux-gnu]</literal> 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.
</para>
</sect2>
<sect2 role="configuration">
<title>Configuring Rust</title>
<sect3 id="rustc-config">
<title>Configuration Information</title>
<para>
If you installed <application>rustc</application> in
<filename class="directory">/opt</filename>, you need to update the
following configuration files so that <application>rustc</application>
is correctly found by other packages and system processes.
</para>
<note>
<para>
The following command depends on the files created in
<xref linkend="bash-profile"/>.
</para>
</note>
<para>
Create the <filename>/etc/profile.d/rustc.sh</filename> startup file as
the &root; user:
</para>
<screen role="root"><userinput>cat &gt; /etc/profile.d/rustc.sh &lt;&lt; "EOF"
<literal># Begin /etc/profile.d/rustc.sh
pathprepend /opt/rustc/bin PATH
# End /etc/profile.d/rustc.sh</literal>
EOF</userinput></screen>
<para>
Immediately after installation, update the current PATH
for your current shell:
</para>
<screen><userinput>source /etc/profile.d/rustc.sh</userinput></screen>
</sect3>
</sect2>
<sect2 role="content">
<title>Contents</title>
<segmentedlist>
<segtitle>Installed Programs</segtitle>
<segtitle>Installed Libraries</segtitle>
<segtitle>Installed Directories</segtitle>
<seglistitem>
<seg>
cargo-clippy, cargo-fmt, cargo, clippy-driver, rust-gdb,
rust-gdbgui, rust-lldb, rustc, rustdoc, and rustfmt
</seg>
<seg>
librustc-driver-&lt;16-byte-hash&gt;.so,
libstd-&lt;16-byte-hash&gt;.so, and
libtest-&lt;16-byte-hash&gt;.so
</seg>
<seg>
~/.cargo,
/opt/rustc, symbolic link to
/opt/rustc-&rust-version;
</seg>
</seglistitem>
</segmentedlist>
<variablelist>
<bridgehead renderas="sect3">Short Descriptions</bridgehead>
<?dbfo list-presentation="list"?>
<?dbhtml list-presentation="table"?>
<varlistentry id="cargo-clippy">
<term><command>cargo-clippy</command></term>
<listitem>
<para>
provides lint checks for a cargo package
</para>
<indexterm zone="rust cargo-clippy">
<primary sortas="b-cargo-clippy">cargo-clippy</primary>
</indexterm>
</listitem>
</varlistentry>
<varlistentry id="cargo-fmt">
<term><command>cargo-fmt</command></term>
<listitem>
<para>
formats all bin and lib files of the current crate using
rustfmt
</para>
<indexterm zone="rust cargo-fmt">
<primary sortas="b-cargo-fmt">cargo-fmt</primary>
</indexterm>
</listitem>
</varlistentry>
<!-- <varlistentry id="cargo-miri">
<term><command>cargo-miri</command></term>
<listitem>
<para>
is for use by Miri to interpret bin crates and tests. It is
not installed by default.
</para>
<indexterm zone="rust cargo-miri">
<primary sortas="b-cargo-miri">cargo-miri</primary>
</indexterm>
</listitem>
</varlistentry>-->
<varlistentry id="cargo">
<term><command>cargo</command></term>
<listitem>
<para>
is the Package Manager for Rust
</para>
<indexterm zone="rust cargo">
<primary sortas="b-cargo">cargo</primary>
</indexterm>
</listitem>
</varlistentry>
<varlistentry id="clippy-driver">
<term><command>clippy-driver</command></term>
<listitem>
<para>
provides lint checks for Rust
</para>
<indexterm zone="rust clippy-driver">
<primary sortas="b-clippy-driver">clippy-driver</primary>
</indexterm>
</listitem>
</varlistentry>
<!-- <varlistentry id="miri">
<term><command>miri</command></term>
<listitem>
<para>
is an interpreter for Rust's mid-level intermediate representation
(MIR). It is not installed by default.
</para>
<indexterm zone="rust miri">
<primary sortas="b-miri">miri</primary>
</indexterm>
</listitem>
</varlistentry>
<varlistentry id="rls">
<term><command>rls</command></term>
<listitem>
<para>
is the Rust Language Server. This can run in the background to
provide IDEs, editors, and other tools with information about Rust
programs
</para>
<indexterm zone="rust rls">
<primary sortas="b-rls">rls</primary>
</indexterm>
</listitem>
</varlistentry>
<varlistentry id="rust-analyzer">
<term><command>rust-analyzer</command></term>
<listitem>
<para>
is an implementation of Language Server Protocol for the Rust
programming language.
</para>
<indexterm zone="rust rust-analyzer">
<primary sortas="b-rust-analyzer">rust-analyzer</primary>
</indexterm>
</listitem>
</varlistentry>
<varlistentry id="rust-demangler">
<term><command>rust-demangler</command></term>
<listitem>
<para>
converts a list of Rust mangled symbols into a
corresponding list of demangled symbols
</para>
<indexterm zone="rust rust-demangler">
<primary sortas="b-rust-demangler">rust-demangler</primary>
</indexterm>
</listitem>
</varlistentry> -->
<varlistentry id="rust-gdb">
<term><command>rust-gdb</command></term>
<listitem>
<para>
is a wrapper script for gdb, pulling in Python pretty-printing
modules installed in
<filename class="directory">/opt/rustc-&rust-version;/lib/rustlib/etc</filename>
</para>
<indexterm zone="rust rust-gdb">
<primary sortas="b-rust-gdb">rust-gdb</primary>
</indexterm>
</listitem>
</varlistentry>
<varlistentry id="rust-gdbgui">
<term><command>rust-gdbgui</command></term>
<listitem>
<para>
is a wrapper script for a graphical front end to gdb that runs in a
browser
</para>
<indexterm zone="rust rust-gdbgui">
<primary sortas="b-rust-gdbgui">rust-gdbgui</primary>
</indexterm>
</listitem>
</varlistentry>
<varlistentry id="rust-lldb">
<term><command>rust-lldb</command></term>
<listitem>
<para>
is a wrapper script for LLDB (the LLVM debugger)
pulling in the Python pretty-printing modules
</para>
<indexterm zone="rust rust-lldb">
<primary sortas="b-rust-lldb">rust=lldb</primary>
</indexterm>
</listitem>
</varlistentry>
<varlistentry id="rustc">
<term><command>rustc</command></term>
<listitem>
<para>
is the rust compiler
</para>
<indexterm zone="rust rustc">
<primary sortas="b-rustc">rustc</primary>
</indexterm>
</listitem>
</varlistentry>
<varlistentry id="rustdoc">
<term><command>rustdoc</command></term>
<listitem>
<para>
generates documentation from rust source code
</para>
<indexterm zone="rust rustdoc">
<primary sortas="b-rustdoc">rustdoc</primary>
</indexterm>
</listitem>
</varlistentry>
<varlistentry id="rustfmt">
<term><command>rustfmt</command></term>
<listitem>
<para>
formats rust code
</para>
<indexterm zone="rust rustfmt">
<primary sortas="b-rustfmt">rustfmt</primary>
</indexterm>
</listitem>
</varlistentry>
<varlistentry id="libstd">
<term><filename class="libraryfile">libstd-&lt;16-byte-hash&gt;.so</filename></term>
<listitem>
<para>
is the Rust Standard Library, the foundation of portable Rust software
</para>
<indexterm zone="rust libstd">
<primary sortas="c-libstd">libstd-&lt;16-byte-hash&gt;.so</primary>
</indexterm>
</listitem>
</varlistentry>
</variablelist>
</sect2>
</sect1>