Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Создание библиотеки

Мы уже знаем, что для создания 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), которая подходит только для программ на Rust
  • cdylib — Системная динамическая библиотека, которая может быть использована из программ на других языках
  • 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, и затем уже непосредственно наше приложение.