Создание библиотеки
Мы уже знаем, что для создания Rust проекта, который компилируется в исполняемый бинарный файл, используется команда cargo new. Для создания библиотеки используется та же команда, но с флагом --lib:
cargo new my_lib --lib
Флаг --lib указывает, что изначально вместо src/main.rs надо создать src/lib.rs.
├── Cargo.toml
└── src/
└── lib.rs
(На самом деле ничто не мешает иметь и src/main.rs и src/lib.rs одновременно, и так часто и делают)
Теперь в Cargo.toml в секции [package] нам надо указать какой тип библиотеки мы делаем. Для этого используется поле crate-type:
[package]
name = "my_lib"
version = "0.1.0"
edition = "2024"
[lib]
crate-type = ["lib"]
[dependencies]
Для crate-type доступны такие варианты:
lib— Библиотека для программы на Rust. Это означает, что проект может собираться в различные типы библиотек, в зависимости от того, как будет собираться программа, которая библиотеку использует. Единственное, что гарантируется: библиотека будет работоспособна для любого другого Rust проекта.rlib— Статическая библиотека, специфичная для программ на Rust. Представлена файлом с расширением*.rlib.dylib— Динамическая библиотека (*.dllна Windows,*.soна Linux,*.dylibна MacOS), которая подходит только для программ на Rustcdylib— Системная динамическая библиотека, которая может быть использована из программ на других языкахstaticlib— Статическая библиотека (*.aили*.lib). Подходит для статической линковки в программу на языке, отличном от Rust.proc-macro— Библиотека, содержащая процедурный макрос.
Как видно, в общем случае, при разработке библиотеки для других Rust приложений, оптимальным вариантом является crate-type=["lib"].
Осталось написать сам код нашей библиотеки — src/lib.rs. Для наших нужд подойдёт, что угодно: например, функция, складывающая два числа.
#![allow(unused)]
fn main() {
pub fn sum2(a: i32, b: i32) -> i32 {
a + b
}
}
Обратите внимание, что функции, экспортируемые из библиотеки, обязательно должны быть отмечены ключевым словом pub.
Использование бибилотеки
Как мы знаем, когда мы указываем библиотеку в секции [dependencies] в Cargo.toml, то Cargo пытается найти соответствующий крэйт на crates.io.
Однако, Cargo умеет скачивать зависимости не только с crates.io, но и из:
- git репозиториев
[dependencies] крэйт = { git = "https://github.com/аккаунт/репозиторий.git", branch = "main" } - локальной файловой системы
[dependencies] крэйт = { path = "/путь/к/коду/" } - альтернативных репозиториев
[dependencies] крэйт = { version = "1.0", registry = "репозиторий" }
В том же каталоге, где мы создали проект библиотеки my_lib, создадим новый проект, который подключит нашу библиотеку в качестве зависимости.
cargo new lib_usage --bin
Откроем Cargo.toml для свежесозданного проекта, и подключим зависимость на my_lib, путём указания пути к её каталогу.
[package]
name = "lib_usage"
version = "0.1.0"
edition = "2024"
[dependencies]
my_lib = { path = "../my_lib" }
Теперь в src/main сделаем простейший пример использования нашей библиотеки.
use my_lib::sum2;
fn main() {
println!("sum2(1,2)={}", sum2(1, 1));
}
И запустим:
lib_usage$ cargo run
Locking 1 package to latest Rust 1.89.0 compatible version
Compiling my_lib v0.1.0 (/home/user/projects/rust/my_lib)
Compiling lib_usage v0.1.0 (/home/user/projects/rust/lib_usage)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.23s
Running `target/debug/lib_usage`
sum2(1,2)=2
В логах сборки можно увидеть, как сначала компилируется зависимость my_lib, и затем уже непосредственно наше приложение.