Build Tools

Rust Tools

External links:

rustup component add rustfmt 
rustup component add rust-src
git clone https://github.com/AstroNvim/AstroNvim ~/.config/nvim
nvim +PackerSync

# After install use commands:
:LspInstall rust -> rust-analyzer
:TSInstall rust
  • Neovide GUI upgrade on Astro Vim
git clone https://github.com/neovide/neovide
cd neovide
cargo build --release
  • EVCXR or iRUST REPL
cargo install evcxr_repl
cargo install irust

VSCode Extensions for Rust

  • CodeLLDB
  • Dependi (бывш crates) - сообщает, если пакеты устарели

VSCode Settings

(For CodeLLDB) Allow breakpoints everywhere: "debug.allowBreakpointsEverywhere": true cargo check: поменять check на clippy: "rust-analyzer.check.command": "clippy"

Rust Prelude

Rust has a Prelude - a set of libraries included in every project. See current libs included in Prelude

User input

std::io::stdin library is used to get user input from standard input stream. Not included in Prelude:

use std:io

let mut guess = String::new();
io::stdin().read_line(&mut guess).expect("Failed to load");

.expect handles Err variant of read_line function, crashing the program with the defined error message.

Subsections of Build Tools

Bacon

Links:

Bacon

Bacon - CLI-утилита запуска команд сборки или тестов по триггеру.

Установка

cargo install --locked bacon
bacon test # run from project folder 

Настройка

Запуск команды инициализации:

bacon --init

Приводит к появлению в папке проекта файла bacon.toml с разными вариантами команд, и можно дописать свою секцию, например:

[jobs.check-examples]
command = ["cargo", "run", "--example", "iterators"]
watch = ["examples"]
need_stdout = true

command - команда и параметры watch - отслеживаемая папка need_stdout - stdout вывод кода показывать к терминале Далее запуск секции:

bacon check-examples

Интерактивный перезапуск компиляции

This will compile+build the code in examples folder, file “variables.rs”. Very convenient to try test different stuff. For live development do:

bacon run -- -q # сборка и запуск текущего проект
bacon run -- -q --example <файл> # сборка и запуск файла в папке examples

bacon test # запуск unit-тестов (например, определённых для lib.rs)

-q - убрать вывод деталей компиляции

(deprecated) Cargo Watch - интерактивный перезапуск компиляции

This will compile+build the code in examples folder, file “variables.rs”. Very convenient to try test different stuff. For live development do:

cargo watch -q -c -x 'run -q --example variables'

-x - rerun upon code change -c - clear terminal each time -q - quiet mode ❗Проект cargo watch заморожен, более не развивается.

Cargo

Link: Cargo profiles - https://doc.rust-lang.org/cargo/reference/profiles.html Mold linker - https://github.com/rui314/mold

Cargo

Use Cargo for managing projects.

cargo new test_project // create project with binary file src/main.rs
// OR
cargo new test_project --lib // create project with library file src/lib.rs 

cd test_project

Source code is in src folder.

cargo build # build project for debug, do not run
cargo run # build & run project
cargo check # fast compiling
cargo build --release # slow build with optimizations for speed of release version

Documentation of methods & traits used in code can be compiled an opened in browser with Cargo command:

cargo doc --open

Сборка Examples

Create “examples” folder beside the “src” folder. Create a file named, for example, “variables.rs” and place some test code in the folder. Then in the project root folder run:

cargo run --example variables

Диагностика сборки

cargo-bloat для поиска проблем

cargo install cargo-bloat
cargo bloat --release

Определяет, какие зависимости задерживают сборку.

cargo build –timings

Создаёт отчёт в HTML с указанием трат времени:

cargo build --timings
# далее открыть target/cargo-timings/cargo-timing.html

cargo-llvm-lines

Показывает, какие generic-функции создают больше всего нагрузки для LLVM:

cargo install cargo-llvm-lines
cargo llvm-lines --release

Generics создают мономорфизм - каждый новый тип создаёт новый код при сборке.

Ускорение сборки

Профили Cargo

Можно управлять ходом сборки проекта с помощью профилей. В том числе это сильно виляет на скорость сборки. Примеры профилей, которые можно создать в cargo.toml файле:

[profile.dev]
opt-level = 0          # No optimization (fastest compilation LLVM)
debug = 1              # Line info only (not full debug symbols)
codegen-units = 256    # More parallelism (max is 256)
incremental = true     # Recompile only changed code

[profile.release]
opt-level = 3          # Maximum runtime performance
lto = "thin"           # Faster than "fat" LTO, still good optimization
codegen-units = 1      # Better optimization at cost of compile time

Для debug сборок, opt-level = 0 и высокое число codegen-units даю самую высокую скорость сборки (разница в скорости в 108 раз!).

Кеширование сборки зависимостей

С помощью sccache можно кешировать собранные артефакты, в том числе таскать кеш между системами.

# Установка
cargo install sccache

# Применение
export RUSTC_WRAPPER=sccache
cargo build

cargo-wizard - быстрая оптимизация

Простой инструмент выбора типа оптимизации:

cargo install cargo-wizard
cargo wizard

Даёт 3 шаблона: fast compilationfast execution, и small binary size

Удалить лишние неиспользуемые зависимости

cargo install cargo-machete
cargo machete  # находит неиспользуемые crates

Создание RAM-disk для пути сборки

Linux/macOS:

mkdir -p /tmp/rust-target
mount -t tmpfs -o size=8G tmpfs /tmp/rust-target
export CARGO_TARGET_DIR=/tmp/rust-target

Управление потоками сборки

Использовать все ядра, кроме 2 (чтобы ОС не повисла):

cargo build -j $(nproc --ignore=2)

Либо указать в .cargo/config.toml:

[build]
jobs = 8

Panic Response

В ответ на панику, по умолчанию программа разматывает стек (unwinding) - проходит по стеку и вычищает данные всех функций. Для уменьшения размера можно просто отключать программу без очистки - abort. Для этого в файле Cargo.toml надо добавить в разделы [profile]:

[profile.release]
panic = 'abort'

Mold (только для Linux)

Проект для Linux (в macOS есть коммерческий аналог Sold, который ненамного лучше сборщику в XCode 15+, потому использование не оправдано).

Настройка

  • Ubuntusudo apt-get install mold clang
  • Fedorasudo dnf install mold clang
  • Arch Linuxsudo pacman -S mold clang

Создать в проекте папку и файл .cargo/config.toml (либо для всех проектов сразу - папка и файл ~/.cargo/config.toml) и вписать:

[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=mold"]

Где архитектуру нужно заменить на текущую: узнать её командой rustc -vV.

Проверка работы

Для проверки в папке с бинарным файлом запустить команду:

$ readelf -p .comment target/debug/your-app

String dump of section '.comment':
  [     0]  mold 2.4.0 ( ... )

Cargo Workspaces

Links:

Проект с Cargo Workspaces

Объединение кода в 1 проект. В Cargo.toml нужно объявить его структуру:

[package]
name = "ardan_workspace"
version = "0.1.0"
edition = "2021"

[dependencies]

[workspace]
members = [ 
  "session1/hello_world",
  "session1/variables",
]

После этого можно добавлять подпрограммы в members, через cargo new <подрограмма>.

Создание и подключение библиотеки в Workspace

Создание библиотеки вместо бинарника - `cargo new –lib examplelib

Прописать в файле cargo.toml у бинарной программы в workspace зависимость:

<..>

[dependencies]
examplelib = { path = "../examplelib"}

Далее, в код бинарной программы включить функции из библиотеки:

use examplelib::function01; // фукнкция должна быть публичной (pub fn)

Единая инициализация и сборка библиотек зависимостей в Workspace

Создаём проект типа workspace и прописываем в его файле Cargo.toml верхнего уровня все библиотеки с версиями (в примере anyhow) в спец разделе [workspace.dependencies]:

[dependencies]
anyhow.workspace = true

[workspace]
members = ["greeter"]

[workspace.dependencies]
anyhow = "1.0.99"

При этом в отдельном разделе [dependencies] указываем, что библиотеки будут распространяться на весь проект. Далее, создаём модуль внутри workspace (в примере = greeter) и в его файле Cargo.toml прописываем, что библиотека берётся из зависимостей workspace:

[dependencies]
anyhow = { workspace = true }

Можно добавлять features к библиотеке из workspace на этапе описания вложенных модулей:

[dependencies] regex = { workspace = true, features = ["unicode"] }

Проверка зависимостей

Можно построить дерево зависимостей и проверить правильность написания cargo.toml файла:

cargo check
cargo tree

Clippy

Настройка

Clippy идёт в составе стандартной поставки Rustup. Пример конфигурации:

cargo clippy --fix -- \
-W clippy::pedantic \
-W clippy::nursery \
-W clippy::unwrap_used \
-W clippy::expect_used

VSCode Settings

cargo check: поменять check на clippy: "rust-analyzer.check.command": "clippy"

Книга

У Clippy есть своя книга в формате Markdown:

cargo install mdbook
# Run from top level of your rust-clippy directory:
mdbook serve book --open
# Goto http://localhost:3000 to see the book

Исключения

Allow Unused / dead code

Убрать warnings на тему неиспользуемых функций или переменных - самой первой строчкой кода включить директиву:

#![allow(unused)]
fn main() {}

Либо у конкретных функций указывать:

#![allow(dead_code)]
fn some_func() { todo!() }

Panamax

Cargo OFFLINE

Для создания локального сервера можно скачать все пакеты Cargo с помощью проекта Panamax.

cargo install --locked panamax
panamax init ~/test/my-mirror

Нужно зайти в папку my-mirror, проверить настройки в файле mirror.toml. И далее запустить синхронизацию:

panamax sync ~/test/my-mirror

Далее, можно публиковать зеркало по веб через встроенный сервер (по порту 8080):

panamax serve ~/test/my-mirror

На индекс странице сервера будет справка по подключению Rust клиентов к зеркалу. В частности, посредством создания файла настроек ~/.cargo/config :

[source.my-mirror]
registry = "http://panamax.local/crates.io-index"
[source.crates-io]
replace-with = "my-mirror"