$ sudo teach IT
Модуль 9 · Build Scripts

Build Scripts — build.rs

build.rs — специальный скрипт, который Cargo запускает перед компиляцией. Нужен для генерации кода, линковки C-библиотек, проверки среды.

📖 Теория 🕐 ~30 минут
⚙️

Что такое build.rs

Если в корне проекта есть файл build.rs, Cargo компилирует и запускает его перед компиляцией основного кода. Это обычная Rust-программа со специальными инструкциями через println!.

🔧
Линковка C-библиотек
Найти и указать компилятору где искать .so / .dylib / .dll файлы
📝
Генерация кода
Создать .rs файлы из протобуферов, SQL-схем, конфигов
🔍
Проверка среды
Проверить наличие системных библиотек, версию компилятора
🏷️
Встраивание метаданных
Записать git-хэш, дату сборки как константы в код
💡

Простой пример — встроить дату сборки

build.rs (корень проекта)
fn main() {
    // cargo:rustc-env=ИМЯ=ЗНАЧЕНИЕ — создаёт переменную среды для компиляции
    println!("cargo:rustc-env=BUILD_DATE=2026-05-27");

    // Перезапускать build.rs только если изменился build.rs
    println!("cargo:rerun-if-changed=build.rs");
}
src/main.rs — использование
fn main() {
    // env! читает переменную среды на этапе компиляции
    println!("Built on: {}", env!("BUILD_DATE"));
}
💡 Переменные заданные через cargo:rustc-env= доступны в коде через макрос env!("ИМЯ") — значение подставляется при компиляции, не в рантайме.
📋

Инструкции для Cargo

build.rs общается с Cargo через специальные println!:

build.rs
// Указать директорию для поиска нативных библиотек
println!("cargo:rustc-link-search=/usr/local/lib");

// Слинковать нативную библиотеку
println!("cargo:rustc-link-lib=ssl");

// Передать флаг компилятору
println!("cargo:rustc-cfg=feature_flag");

// Создать переменную среды для кода
println!("cargo:rustc-env=MY_VAR=value");

// Перезапустить build.rs если изменился файл
println!("cargo:rerun-if-changed=wrapper.h");

// Перезапустить если изменилась переменная среды
println!("cargo:rerun-if-env-changed=CC");
⚠️ Если не указать rerun-if-changed, build.rs будет перезапускаться при каждой сборке. Всегда добавляйте хотя бы cargo:rerun-if-changed=build.rs.
📦

build-dependencies — зависимости для build.rs

build.rs может использовать крейты — они указываются в [build-dependencies] и НЕ попадают в финальный бинарник:

Cargo.toml
[build-dependencies]
# Популярные крейты для build.rs:
cc = "1"           # компиляция C/C++ кода
prost-build = "0.13"  # генерация кода из .proto файлов
bindgen = "0.70"   # генерация bindings из C заголовков
📌 Что важно запомнить
→ build.rs — Rust-скрипт в корне, запускается до компиляции основного кода
→ Общение с Cargo через println!("cargo:инструкция=значение")
→ cargo:rustc-env=VAR=VAL — создать переменную для env!() в коде
→ cargo:rerun-if-changed= — когда перезапускать build.rs
→ [build-dependencies] — крейты только для build.rs

Тест

3 вопроса