Hello, Cargo!

Cargo — это инструмент, который используют разработчики для управления своими Rust проектами. Работа над Cargo пока ещё не закончена. Сейчас он находится в состоянии pre-1.0. Тем не менее, он уже достаточно хорош для использования во многих Rust проектах, и поэтому предполагается, что проекты на Rust будут использовать Cargo с самого начала.

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

Если вы использовали официальный установщик, то Cargo установился вместе с Rust. Если же вы установили Rust каким-либо другим образом, вы можете посмотреть инструкции по установке Cargo.

Переходим на Cargo

Давайте начнём использовать Cargo для сборки кода нашей программы «Hello World».

Чтобы Cargo-фицировать ваш проект, вы должны сделать две вещи: создать конфигурационный файл Cargo.toml и поместить файл с исходным кодом в правильное место. Давайте сделаем это:

$ mkdir src
$ mv main.rs src/main.rs

Отметим, что поскольку мы создаём исполняемый файл, то мы использовали main.rs. Если же вместо этого мы хотим сделать библиотеку, то мы должны использовать lib.rs. Специальное расположение файла для точки входа может быть задано с помощью ключа [[lib] или [[bin]]]crates-custom в файле TOML, который описывается ниже.

Cargo ожидает что ваши файлы с исходным кодом находятся в директории src. Это оставляет верхний уровень для других вещей вроде README, файлов с текстом лицензии и других не относящихся к вашему коду. Cargo помогает нам сохранять наши проекты красивыми и аккуратными. Всему своё место и всё на своём месте.

Дальше, создадим конфигурационный файл для Cargo:

$ editor Cargo.toml

Убедитесь, что имя правильное: вам нужна заглавная C!

Вставьте эту конфигурацию в свой Cargo.toml:

[package]

name = "hello_world"
version = "0.0.1"
authors = [ "Ваше имя <you@example.ru>" ]

Этот файл в формате TOML. Позволим ему самому рассказать о себе:

TOML стремится быть минималистичным форматом для конфигурационных файлов, который легко читается благодаря понятной семантике. TOML спроектирован для однозначного отображения в хэш-таблицу. TOML должен легко преобразовываться в структуры данных широкого спектра языков программирования.

TOML очень похож на INI, но с некоторыми дополнительными возможностями.

Итак, мы с этим закончили и готовы к сборке! Попробуйте собрать:

$ cargo build
   Compiling hello_world v0.0.1 (file:///home/yourname/projects/hello_world)
$ ./target/debug/hello_world
Привет, мир!

Та-да! Мы собрали наш проект вызвав cargo build и запустили его с помощью ./target/debug/hello_world. Мы можем сделать это в один шаг используя cargo run:

$ cargo run
     Running `target/debug/hello_world`
Привет, мир!

Заметьте, что сейчас мы не пересобирали наш проект. Cargo понял, что мы не изменили файл с исходным кодом и только лишь запустил исполняемый файл. Если бы мы изменили файл, мы бы увидели оба шага:

$ cargo run
   Compiling hello_world v0.0.1 (file:///home/yourname/projects/hello_world)
     Running `target/debug/hello_world`
Привет, мир!

На первый взгляд это кажется сложнее, по сравнению с более простым использованием rustc, но подумаем о будущем: если бы в нашем проекте было больше одного файла, мы бы должны были вызвать rustc для каждого и передать ему кучу параметров, что бы собрать их все вместе. С Cargo, когда наш проект вырастет, нам понадобится вызвать только команду cargo build и она всё сделает за нас.

Когда вы закончите работать над проектом, и он окончательно будет готов к релизу, то можете использовать команду cargo build --release для компиляции ваших контейнеров (crates) с оптимизацией.

Так же вы должны были заметить, что Cargo создал новый файл: Cargo.lock.

[root]
name = "hello_world"
version = "0.0.1"

Этот файл используется Cargo для отслеживания зависимостей в вашем приложении. Прямо сейчас у нас нет ни одной, поэтому этот файл немного пустоват. Вам не нужно редактировать этот файл самостоятельно, Cargo сам с ним разберётся.

Так! Мы успешно собрали hello_world с помощью Cargo. Несмотря на то, что наша программа проста, мы использовали большую часть реальных инструментов, которые вы будете использовать в своём дальнейшем пути Rust программиста. Вы можете использовать их во всех Rust проектах:

$ git clone someurl.com/foo
$ cd foo
$ cargo build

Новый проект

Вам не нужно повторять вышеприведённые шаги каждый раз, когда вы хотите создать новый проект! Cargo может создать директорию проекта, в котором вы сразу сможете приступить к разработке.

Чтобы создать новый проект с помощью Cargo, нужно ввести команду cargo new:

$ cargo new hello_world --bin

Мы указываем аргумент --bin, т.к. хотим создать исполняемую программу. Если мы не укажем этот аргумент, то Cargo создаст проект для библиотеки.

Давайте теперь посмотрим на то, что Cargo создал нам:

$ cd hello_world
$ tree .
.
├── Cargo.toml
└── src
    └── main.rs

1 директория, 2 файла

Если у вас нет команды tree, то скорее всего эта программа не установлена в вашей системе. Попробуйте установить её через менеджер пакетов вашего дистрибутива. Это не обязательно, но данная утилита очень полезна.

Все файлы и директории уже на месте. Теперь можем начинать. Для начала проверим файл Cargo.toml:

[package]

name = "hello_world"
version = "0.0.1"
authors = ["Ваше Имя <you@example.ru>"]

Cargo наполнил этот файл значениями по умолчанию на основании переданных аргументов и глобальной конфигурации git. Обратите внимание, что Cargo уже в директории hello_world создал репозиторий для git.

Также заглянем в src/main.rs:

fn main() {
    println!("Привет, мир!");
}

Cargo создал «Hello World!» для нас и вы уже можете приступить к программированию! У Cargo есть собственное руководство в котором про него рассказано более полно.

Теперь давайте отложим инструментарий и узнаем больше о самом языке. Это основы, которые вы будете часто использовать на протяжении всего вашего взаимодействия с Rust.

У вас есть два пути: погрузиться в изучение реального проекта, раздел «Изучение Rust», или начать с самого низа и постепенно продвигаться наверх, раздел «Синтаксис и семантика». Программисты, имеющие опыт работы с системными языками, вероятно, предпочтут «Изучение Rust», в то время как программисты, имеющие опыт работы с динамическими языками, вполне возможно, пойдут по второму пути. Разные люди учатся по-разному! Выберите то, что подходит именно вам.