Как собрать несколько исполняемых бинарных файлов в одном проекте Cargo?
Основной способ: папка src/bin/ и явное указание в Cargo.toml
Вы на правильном пути! В Rust/Cargo есть несколько способов определить несколько бинарников. Самый простой и рекомендуемый — использовать папку src/bin/. Каждый файл .rs внутри этой папки автоматически становится отдельным бинарником, имя которого соответствует имени файла (без расширения).
Ваша структура my_project/src/bin/log_parser.rs и my_project/src/bin/report_gen.rs — это корректный подход. Проблема может быть в том, что у вас остался src/main.rs. Если он существует, Cargo воспринимает его как основной бинарник проекта (с именем, равным имени пакета). Это не мешает другим бинарникам, но если вы хотите, чтобы cargo build собирал все бинарники, нужно убедиться, что в Cargo.toml нет конфликтующих настроек.
Вот правильная конфигурация Cargo.toml для вашего случая:
[package]
name = "my_project"
version = "0.1.0"
edition = "2021"
# Явно перечисляем все бинарники (опционально, но рекомендуется для больших проектов)
[[bin]]
name = "log_parser"
path = "src/bin/log_parser.rs"
[[bin]]
name = "report_gen"
path = "src/bin/report_gen.rs"
# Если вы хотите удалить src/main.rs и сделать log_parser основным,
# просто удалите src/main.rs и переименуйте файл, или оставьте как есть
Теперь команды для сборки и запуска:
cargo build— соберёт все бинарники. Они появятся вtarget/debug/log_parserиtarget/debug/report_gen.cargo run --bin log_parser— соберёт и запустит толькоlog_parser.cargo run --bin report_gen— аналогично дляreport_gen.cargo build --bin log_parser— соберёт только указанный бинарник (ускоряет сборку при разработке одного из них).
Если вы хотите, чтобы при cargo run (без флага --bin) запускался какой-то конкретный бинарник по умолчанию, можно задать его в Cargo.toml с помощью default-run:
[package]
name = "my_project"
version = "0.1.0"
edition = "2021"
default-run = "log_parser"
[[bin]]
name = "log_parser"
path = "src/bin/log_parser.rs"
[[bin]]
name = "report_gen"
path = "src/bin/report_gen.rs"
Теперь cargo run без аргументов будет запускать log_parser.
Пример кода для бинарников
Вот как могут выглядеть ваши файлы:
src/bin/log_parser.rs:
fn main() {
println!("Log parser started. Parsing logs...");
// Здесь код парсинга
}
src/bin/report_gen.rs:
fn main() {
println!("Report generator started. Generating report...");
// Здесь код генерации отчёта
}
Оба бинарника могут использовать общие модули, если вы вынесете их в src/lib.rs (библиотечный крейт). Например:
// src/lib.rs
pub mod utils;
pub mod data_structures;
// src/bin/log_parser.rs
use my_project::utils;
fn main() {
utils::do_something();
}
Не забудьте добавить pub mod utils; в lib.rs и создать соответствующие файлы.
Если вы не хотите использовать папку bin/, можно разместить бинарники прямо в src/ с разными именами, но тогда придётся явно указывать пути в Cargo.toml. Однако папка src/bin/ — это общепринятый стандарт, рекомендую придерживаться его.
Альтернативный подход: workspace с несколькими крейтами
Если ваши программы сильно различаются и имеют разные зависимости, возможно, лучше использовать workspace (рабочее пространство). Это позволяет держать каждый бинарник в отдельной папке со своим Cargo.toml, но в рамках одного репозитория.
Пример структуры workspace:
my_project/
├── Cargo.toml # workspace-файл
├── log_parser/
│ ├── Cargo.toml
│ └── src/main.rs
└── report_gen/
├── Cargo.toml
└── src/main.rs
Главный Cargo.toml (в корне):
[workspace]
members = [
"log_parser",
"report_gen",
]
Теперь команды работают так же: cargo build --bin log_parser или cargo run -p report_gen (флаг -p — указание пакета).
Плюсы: каждый крейт имеет свои зависимости и версии, изолированная компиляция, проще тестировать по отдельности.
Минусы: сложнее переиспользовать общий код — придётся создавать отдельный библиотечный крейт и добавлять его как зависимость в оба бинарника. Для небольших проектов с общими структурами данных папка src/bin/ удобнее.
Выбирайте подход под свои задачи: если бинарники тесно связаны — используйте src/bin/; если это независимые программы — workspace.
Ответов пока нет.
Войдите чтобы оставить ответ