Привіт, Cargo!
Cargo - це система побудови та пакетний менеджер Rust. Більшість растацеанців використовують цей інструмент для керування проєктами Rust, бо Cargo виконує багато задач, таких, як збірка коду, завантаження бібліотек, від яких залежить ваш код, та збірка цих бібліотек. (Бібліотеки, потрібні коду, звуться залежностями.)
Найпростіші програми Rust, як та, яку ми щойно написали, не мають жодних залежностей. Якби ми зібрали проєкт "Hello world" за допомогою Cargo, то скористалися б тільки тією частиною Cargo, що відповідає з збірку коду. Коли ж ви писатимете складніші програми Rust, то додаватимете залежності, і якщо почнете проєкт за допомогою Cargo, додавати залежності буде значно легше.
Оскільки переважна більшість проєктів Rust використовують Cargo, надалі в книзі вважатиметься, що ви теж використовуєте Cargo. Cargo встановлюється з Rust, якщо ви скористалися офіційним встановлювачем, як сказано в підрозділі Встановлення . Якщо ви встановили Rust у інший спосіб, перевірте, чи встановлений Cargo, ввівши це у свій термінал:
$ cargo --version
Якщо ви побачите номер версії, то Cargo встановлений! Але якщо ви бачите помилку на кшталт не знайдено команду
, зверніться до документації по вашому методу встановлення, щоб визначити, як окремо встановити Cargo.
Створення проєкту за допомогою Cargo
Створімо новий проєкт за допомогою Cargo і подивімося, як він відрізняється від нашого початкового проєкту Hello World. Поверніться до вашої теки projects (чи іншої, де ви зберегли ваш код) і введіть команди (незалежно від системи):
$ cargo new hello_cargo
$ cd hello_cargo
Перша команда створює нову теку і проєкт, що зветься hello_cargo. Ми назвали наш проєкт hello_cargo, і Cargo створює свої файли у теці з такою назвою.
Перейдіть до теки hello_cargo і перегляньте файли. Ви побачите, що Cargo створив два файли і одну теку: Cargo.toml і теку src із файлом main.rs.
Також він розпочав новий репозиторій Git, додавши файл .gitignore. Файли Git не будуть створені, якщо ви запустите cargo new
в уже створеному репозиторії Git; ви можете змінити цю поведінку за допомогою cargo new --vcs=git
.
Примітка: Git - це поширена система контролю версій. Ви можете сказати
cargo new
використовувати іншу систему контролю версій чи не використовувати жодної за допомогою прапорця--vcs
. Запустітьcargo new --help
, щоб побачити можливі варіанти.
Відкрийте файл Cargo.toml у будь-якому текстовому редакторі. Він має виглядати десь так, як показано у Роздруку 1-2.
Файл: Cargo.toml
[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["Ваше Ім'я <email@example.com>"]
edition = "2018"
[dependencies]
Це файл у форматі TOML (Tom’s Obvious, Minimal Language - "Томова очевидна мінімальна мова"), який Cargo використовує як формат для конфігурації.
Перший рядок, [package]
(пакет) - це заголовок розділу, що показує, що наступні інструкції стосуються конфігурації пакета. Коли ми додамо більше інформації до цього файлу, ми додамо й інші розділи.
Наступні три рядки встановлюють конфігураційну інформацію, потрібну Cargo для компілювання вашої програми: ім'я, версію і яке видання Rust використовувати. Про ключ edition
(видання) детальніше розповідається в Додатку E.
Останній рядок, [dependencies]
, розпочинає розділ, де можна вказувати залежності вашого проєкту. Пакети з кодом в Rust звуться крейтами (<0>crate</0>). Нам не потрібні інші крейти для цього проєкту, але вони знадобляться для першого проєкту у Розділі 2, і тоді ми скористаємося цим розділом.
Тепер відкрийте файл src/main.rs і подивіться на його вміст:
Файл: src/main.rs
fn main() { println!("Hello, world!"); }
Cargo створив для вас “Hello World!”, точно такий, який ми написали в Роздруку 1-1! Поки що відмінності між нашим попереднім проєктом та згенерованим Cargo полягає в тому, що Cargo розмістив код у теці src і додав конфігураційний файл Cargo.toml в основній теці.
Cargo очікує, що вихідні файли будуть розташовані в теці src, а основна тека міститиме лише README, ліцензійну інформацію, конфігураційні файли і все таке, що не стосується вашого коду. Використання Cargo допомагає організувати ваші проєкт. Все має своє місце, і все лежить на своїх місцях.
Якщо ви почали проєкт, що не використовує Cargo, як було із нашим проєктом “Hello, world!” , його можна перетворити на проєкт із підтримкою Cargo, перемістивши код до теки src і створивши відповідний файл Cargo.toml.
Побудова і запуск проєкту Cargo
Погляньмо, як відрізняється збірка і запуск програми “Hello, world!” за допомогою Cargo. Зберіть проєкт такими командами з теки hello_cargo:
$ cargo build
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs
Ця команда створить виконанний файл target/debug/hello_cargo (чи target\debug\hello_cargo.exe на Windows), а не в поточній теці. Оскільки усталена збірка - дебажна, Cargo розміщує двійковий файл у теці, що зветься debug. Виконуваний файл можна запустити такою командою:
$ ./target/debug/hello_cargo # чи .\target\debug\hello_cargo.exe на Windows
Hello, world!
Якщо все пройшло добре, в термінал виведеться Hello, world!
. Запуск cargo build
уперше також призводить до створення Cargo нового файлу в теці верхнього рівня: Cargo.lock. Цей файл відстежує конкретні версії залежностей вашого проєкту. Цей проєкт не має залежностей, тому файл дещо порожній. Вам не треба нічого самостійно змінювати у цьому файлі, його вмістом займається Cargo.
We just built a project with cargo build
and ran it with ./target/debug/hello_cargo
, but we can also use cargo run
to compile the code and then run the resulting executable all in one command:
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/hello_cargo`
Hello, world!
Використання cargo run
зручніше, ніж запам'ятовувати виконати cargo build
, а потім писати весь шлях до двійкового файлу, тому більшість розробників використовують cargo run
.
Зверніть увагу, що цього разу ми не побачили повідомлення про те, що Cargo компілює hello_cargo
. Cargo зрозумів, що файли не змінилися, тому не перезібрав, а просто запустив двійковий файл. Якби ви змінили вихідний код, Cargo б довелося перебудувати проєкт перед виконанням, і ви б побачили такий вивід:
$ cargo run
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
Running `target/debug/hello_cargo`
Hello, world!
Крім того, Cargo має команду cargo check
. Ця команда швидко перевіряє ваш код, щоб переконатися, що він компілюється, але не створює виконанного файлу:
$ cargo check
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
Чому виконуваний файл може бути непотрібним? cargo check
зазвичай працює значно швидше за cargo build
, бо пропускає створення виконанного файлу. Якщо ви постійно перевіряєте свій код під час його написання, використання cargo check
дозволить вам швидше дізнатися, чи ваш проєкт все ще компілюється! Ось чому багато растацеанців запускають cargo check
час від часу поки пишуть програму, щоб переконатися, що вона компілюються, а потім запускають cargo build
, коли готові працювати з виконуваним файлом.
Підіб'ємо підсумок, що ж ми дізналися про Cargo:
- Ми можемо створити проєкт за допомогою
cargo new
. - Ми можемо зібрати проєкт за допомогою
cargo build
. - Ми можемо зібрати і запустити проєкт в одну дію за допомогою
cargo run
. - Ми можемо зібрати проєкт без створення двійкового файлу для пошуку помилок за допомогою
cargo check
. - Cargo зберігає результат збірки не в одній теці з кодом, а в теці target/debug.
Додаткова перевага використання Cargo полягає в тому, що його команди однакові незалежно від операційної системи, в якій ви працюєте. Тому з цього моменту ми більше не надаватимемо окремих команд для Linux, macOS чи Windows.
Збірка для релізу
Коли ваш проєкт нарешті готовий для релізу, ви можете запустити cargo build --release
, щоб скомпілювати його з оптимізаціями. Ця команда створить виконуваний файл у теці target/release замість target/debug. Ці оптимізації дозволяють коду Rust працювати швидше, але подовжують час, потрібний для компіляції програми. Ось чому є два різні профілі: один для розробки, щоб можна було перебудовувати часто і швидко, і другий для збірки фінальної програми, яку можна дати користувачеві, яку не треба часто перебудовувати і яка буде виконуватися якомога швидше. Якщо ви робите бенчмарк вашого коду, запускайте cargo build --release
і робіть бенчмарк виконуваного файлу у target/release.
Cargo як загальна домовленість
У простих проєктах Cargo надає ненабагато більше можливостей за rustc
, але в подальшому він виявить свою цінність, коли ваші програми стануть складнішими. Щойно програми доростають до декількох файлів чи потребують залежності, набагато простіше дозволити Cargo координувати збірку.
Хоча проєкт hello_cargo
і нескладний, тепер він використовує багато інструментів, якими ви будете користуватися решту вашої кар'єри з Rust. Фактично, щоб працювати із будь-яким існуючим проєктом ви можете скористатися цими командами, щоб завантажити код за допомогою Git, перейти до теки проєкту і зібрати його:
$ git clone someurl.com/someproject
$ cd someproject
$ cargo build
Для отримання додаткової інформації про Cargo перегляньте документацію.
Підсумок
Це був непоганий початок вашої подорожі по Rust! У цьому розділі ви навчилися:
- Встановлювати останню стабільну версію Rust за допомогою
rustup
- Оновлюватися до нової версії Rust
- Відкривати локально встановлену документацію
- Писати і запускати програму “Hello, world!” за допомогою
rustc
безпосередньо - Створювати і запускати новий проєкт за допомогою домовленостей Cargo
Настав час побудувати більш змістовну програму, щоб призвичаїтися до читання та написання коду Rust. У Розділі 2 ми створимо програму для відгадування числа. Якщо ви натомість бажаєте почати з вивчення, як загальні концепції програмування працюють в Rust, переходьте до Розділу 3, а потім поверніться до Розділу 2.