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 ( ... )