Управление зависимостями в Rust с Cargo

6f14b77bbc52581c0d7dbf3afda928fb.png

Привет!

Cargo — это хороший менеджер пакетов Rust, который берет на себя тяжелую работу по управлению зависимостями, сборке проекта, тестированию и многому другому.

Cargo

Cargo — это официальный менеджер пакетов и система сборки для Rust. Он был разработан для упрощения работы с кодом на Rust, обеспечивая единообразную сборку проектов, управление зависимостями, ну и плюсом тестирование. Как npm для Node.js или Maven для Java — Cargo играет аналогичную роль для Rust.

Основные возможности:

Cargo автоматически скачивает нужные библиотеки (которые называются «crates» в Rust) и их зависимости. Cargo компилирует код, используя правильные версии зависимостей и параметры сборки.

Cargo позволяет публиковать свои crates на crates.io.

Установим и настроим

Cargo поставляется вместе с Rust, поэтому, если уже установлен Rust, то Cargo уже установлен:

rustc --version

Если видно версию Rust, значит, все ок

Настроим рабочее окружение:

Создадим каталог, в котором будем работать (папку). Переходим в рабочий каталог с помощью терминала и выполняем команду инициализации проекта:

[dependencies]
my_library = "^1.2.3"

Это крейтит файл Cargo.toml и каталог src с файлом main.rs, где в будущем будем писать код. Через консоль можно создать каталог таким образом:

$ cargo new hello_world --bin

Открываем файл Cargo.toml в текстовом редакторе. В этом файле будем указывать зависимости и настройки проекта.

Файл Cargo.toml

Секция [dependencies] используется для определения основных зависимостей проекта. Эти зависимости будут установлены при сборке проекта для всех конфигураций:

[package]
name = "my_project"
version = "0.1.0"
edition = "2018"
[dependencies]
my_library = "1.2.3"

Секция [dev-dependencies] используется для зависимостей, которые нужны только во время разработки, например, для юнит-тестирования. Они не будут включены в финальную сборку проекта:

[dev-dependencies]
test_framework = "0.5.0"

Секция [build-dependencies] используется для зависимостей, которые нужны только во время сборки проекта:

[build-dependencies]
codegen_tool = "0.1.0"

Можно определить опциональные зависимости в разных конфигурациях:

[dependencies]
my_library = { version = "1.2.3", optional = true }

[target] позволяет определять зависимости, которые специфичны для определенных архитектур или целей сборки, таких как build.rs:

[target.'cfg(target_os = "windows")'.dependencies]
windows_library = "2.0.0"

Для сборки проекта, выполняем команду cargo build в терминале. Cargo соберет проект, включая все зависимости. Если будут ошибки, то это все отобразится.

Ограничения на версии

Ограничения на версии позволяют указать диапазон версий, которые хотим использовать. Примеры ограничений:

  • =: Использовать только конкретную версию.

  • >=: Использовать версии, равные или новее указанной.

  • <=: Использовать версии, равные или старше указанной.

  • ~: Использовать версии, которые совместимы с указанной версией, но не изменяют MAJOR версию.

  • ^: Использовать версии, которые совместимы с указанной версией, но не изменяют MAJOR и MINOR версии.

  • !=: Исключить определенные версии.

SemVer — это соглашение о формате версий библиотек и зависимостей, которое позволяет определить, какие изменения были внесены в новой версии и какие возможности могут быть нарушены для разработчиков, использующих эту зависимость. SemVer включает в себя три компонента версии: MAJOR, MINOR и PATCH.

MAJOR (главный номер): увеличивается, когда вносятся обратно несовместимые изменения API.

MINOR (минорный номер): увеличивается, когда добавляются новые функциональные возможности, но с сохранением обратной совместимости. Новые функции могут быть добавлены, но существующий код должен продолжать работать.

PATCH (патч-номер): увеличивается, когда вносятся исправления ошибок или изменения, которые сохраняют обратную совместимость, означает, что внесенные изменения исправляют ошибки, но не меняют функциональность.

Предположим, у нас есть зависимость в файле Cargo.toml следующего вида:

[dependencies]
my_library = "1.2.3"

MAJOR (главный номер) равен 1. Это означает, что мы используем главную версию этой библиотеки.

MINOR (минорный номер) равен 2. Это указывает на минорные обновления с новыми функциональными возможностями, но с обратной совместимостью.

PATCH (патч-номер) равен 3. Это обновление исправлений и изменений с обратной совместимостью.

Примеры ограничений:

Использовать версии от 1.2.3 до 2.0.0 (включительно):

my_library >= "1.2.3", <= "2.0.0"

Использовать версии совместимые с 1.2.0, но не изменяющие MAJOR версию:

my_library = "~1.2.0"

Использовать версии совместимые с 1.2.0, но не изменяющие MAJOR и MINOR версии:

my_library = "^1.2.0"

После указания зависимостей и их ограничений в Cargo.toml, можно выпнолить команду cargo update в командной строке в корневой директории проекта. Cargo обновит зависимости в соответствии с указанными ограничениями и загрузит подходящие версии.

В продолжение темы хочу напомнить про бесплатные вебинары от экспертов рынка про безопасный unsafe Rust и про то,  как Rust побуждает использовать композицию.

А больше курсов от экспертов OTUS можно найти в полном каталоге.

© Habrahabr.ru