← Оглавление

9.3 Из горна

Артефакт прошёл заставу. Тесты проходят, порт доказывает себя, журнал ведётся, дверь закрывается чисто. Всё это - в мастерской, с отладочной сборкой: без оптимизаций, с именами функций и номерами строк, которые нужны отладчику и бесполезны пользователю. Мастерская - не мир. То, что выходит наружу, собирается по другим правилам.

Что нужно

cargo build - отладочная сборка. Компилятор торопится: не оптимизирует, сохраняет всё. Бинарник tq в target/debug/ весит 21 мегабайт. Внутри - имена всех функций, номера строк исходника, данные для отладчика. Пользователю ничего этого не нужно.

cargo build --release включает другой профиль. Компилятор перестаёт торопиться: применяет оптимизации, убирает мёртвый код. Профиль можно настроить в корневом Cargo.toml - там задают, что именно значит “релиз” для этого проекта. Два параметра дают наибольший эффект.

lto = true - link-time optimization. Обычно каждый крейт компилируется отдельно; компоновщик соединяет объектные файлы после. При lto = true компилятор видит весь граф программы целиком в момент компоновки: убирает функции, которые никто не вызывает, встраивает мелкие функции, удаляет ветки, которые никогда не выполняются. Бинарник меньше, работает быстрее.

strip = true - выбрасывает символы отладчика из финального бинарника. Имена функций, пути к исходникам, номера строк - всё это не нужно пользователю.

Постройка

В корневой Cargo.toml добавьте секцию после [workspace]:

[profile.release]
lto = true
strip = true

В Makefile добавьте цель в секцию BUILD, перед clean:

## release: build optimized stripped binaries
.PHONY: release
release:
	@cargo build --release -p tq-cli -p tq-api
	@ls -lh target/release/tq target/release/tq-api

Результат

$ make release
    Finished `release` profile [optimized] target(s) in 53.72s
-rwxrwxr-x 1 user user 1.1M target/release/tq
-rwxrwxr-x 1 user user 1.7M target/release/tq-api

target/debug/tq весил 21 мегабайт. target/release/tq - 1.1. В двадцать раз меньше. Отладочный бинарник - черновик с пометками на полях. Из мастерской выходит готовое изделие.

Готовый артефакт запускается без Rust:

$ ./target/release/tq list
$ ./target/release/tq-api

tasks.json сохраняется между запусками - данные из предыдущих глав никуда не делись.

make ci проверяет правильность. make release собирает то, что передают.

Полный код этой главы находится в 9-shippable/03-forged/.


Lore: что хранится в отладочной сборке

В отладочной сборке бинарник содержит секцию .debug_info - данные в формате DWARF. Там имена переменных и функций, пути к файлам исходников, номера строк, типы. Отладчик (gdb, lldb) читает эту секцию, чтобы показывать “ты остановился на строке 42 в store.rs” вместо “ты остановился по адресу 0x4a3f12”. strip = true удаляет эту секцию; поведение программы не меняется.

Можно удалить только часть: strip = "debuginfo" уберёт отладочные данные, но сохранит имена символов - полезно, если нужно профилировать релизную сборку.

[profile.release] принимает много параметров: opt-level, codegen-units, panic, overflow-checks и другие. Оптимальный набор зависит от задачи - встроенная система, серверное приложение и CLI требуют разных компромиссов. Полный список с объяснениями - в документации Cargo.