Как использовать локальный неопубликованный крейт (crate) в Rust?
Правильный способ подключения локального крейта через путь
Ваша основная идея верна — использование path в Cargo.toml — это стандартный способ подключения локального неопубликованного крейта. Однако ошибка возникает из-за того, что Cargo не может найти крейт по указанному пути. Давайте разберёмся по шагам.
Шаг 1: Проверьте структуру папок
Убедитесь, что путь в path указан относительно файла Cargo.toml, который его содержит. В вашем случае ../my_lib означает «подняться на уровень выше и войти в папку my_lib». Если структура именно такая, как вы описали, путь корректен. Но часто начинающие путают относительные пути — попробуйте указать абсолютный путь для проверки:
[dependencies]
my_lib = { path = "/полный/путь/до/my_lib" }
Если это сработает, значит проблема именно в относительном пути. Рекомендую использовать относительные пути, но проверьте, что вы запускаете cargo build именно из папки my_app.
Шаг 2: Убедитесь, что крейт — библиотека
Ваш my_lib должен быть библиотекой (lib), а не исполняемым файлом (bin). В my_lib/Cargo.toml не должно быть секции [[bin]], а в src/lib.rs — функции main. Если вы случайно создали бинарный крейт, добавьте в Cargo.toml:
[lib]
name = "my_lib"
path = "src/lib.rs"
Или просто переименуйте src/main.rs в src/lib.rs.
Шаг 3: Правильная структура проекта (рекомендуемый способ)
Лучшая практика для Rust-проектов с локальными зависимостями — использовать workspace. Это позволяет управлять несколькими крейтами в одном репозитории. Создайте корневой Cargo.toml:
[workspace]
members = [
"my_lib",
"my_app",
]
Теперь переместите папки my_lib и my_app внутрь корневой директории проекта. В my_app/Cargo.toml зависимость будет выглядеть так:
[dependencies]
my_lib = { path = "../my_lib" } # относительно my_app
Или, если вы используете workspace, можно указать просто имя крейта, и Cargo сам найдёт его среди членов workspace:
[dependencies]
my_lib = { path = "../my_lib" } # всё ещё работает, но можно и без path, если крейт опубликован
Шаг 4: Проверьте версию и имя крейта
Убедитесь, что в my_lib/Cargo.toml поле name совпадает с тем, что вы указываете в зависимости. Регистр важен: my_lib и My_Lib — разные имена. Также проверьте, что версия указана (хотя для локальных путей это не обязательно).
Полный пример рабочей конфигурации
my_lib/Cargo.toml:
[package]
name = "my_lib"
version = "0.1.0"
edition = "2021"
[lib]
name = "my_lib"
path = "src/lib.rs"
my_lib/src/lib.rs:
pub fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
my_app/Cargo.toml:
[package]
name = "my_app"
version = "0.1.0"
edition = "2021"
[dependencies]
my_lib = { path = "../my_lib" }
my_app/src/main.rs:
use my_lib::greet;
fn main() {
println!("{}", greet("Rust developer"));
}
Что ещё стоит знать?
- Отладка: Запустите
cargo build -v(verbose), чтобы увидеть, какие пути ищет Cargo. - Кэш: Иногда помогает
cargo cleanи повторная сборка. - Git: Если вы используете git, не забудьте добавить
Cargo.lockв репозиторий для воспроизводимости сборок. - Публикация: Когда крейт будет готов, вы сможете легко переключиться с
pathна версию из crates.io, просто заменив зависимость наmy_lib = "0.1.0".
Надеюсь, это поможет! Если ошибка остаётся — проверьте права доступа к папке my_lib и убедитесь, что в ней есть Cargo.toml.
Альтернативный подход: использование git-зависимости
Если вы не хотите использовать workspace или относительные пути (например, когда проект хранится в разных репозиториях), можно подключить локальный крейт через git. Для этого инициализируйте git-репозиторий в папке my_lib и сделайте хотя бы один коммит. Затем в my_app/Cargo.toml укажите:
[dependencies]
my_lib = { git = "file:///полный/путь/до/my_lib" }
Обратите внимание на file:// — это указывает Cargo на локальный git-репозиторий. Преимущество этого метода в том, что вы можете указывать конкретные ветки, теги или коммиты:
my_lib = { git = "file:///путь/до/my_lib", branch = "dev" }
Недостаток — нужно постоянно коммитить изменения в my_lib, чтобы они подтягивались в my_app. Для быстрой разработки это неудобно, но для изолированных проектов или CI/CD может быть полезно.
Также помните: если вы используете git-зависимость, Cargo будет клонировать репозиторий каждый раз при сборке, если не закеширует его. Для локальной разработки путь через path или workspace всё же предпочтительнее.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги
Python для всех: Различия версий, проверка через терминал и стандарты PEP 8