Az előző leckében feltelepítetted a toolchaint a rustup segítségével, ami a rustc fordítót és néhány kísérő eszközt is a gépedre tett — köztük a Cargo-t. A rustc önmagában egyetlen .rs fájlt tud lefordítani, de egy valódi projektben már több fájl, függőségek és tesztek is vannak. Ezt mind a Cargo fogja koordinálni: ez a Rust hivatalos build-eszköze és csomagkezelője egyben, és a mindennapi munkádban ezt fogod használni, nem a rustc-t közvetlenül.

A rustup telepítés után a cargo parancs is azonnal elérhető a terminálban. Ellenőrizd:

cargo --version

Ha látsz egy verziószámot, kész is vagy az induláshoz.

Új projekt indítása: cargo new

A cargo new parancs egy teljesen kész, azonnal fordítható projektet varázsol elő a semmiből:

cargo new hello_cargo

Ez létrehoz egy hello_cargo nevű mappát a következő tartalommal:

hello_cargo/
├── Cargo.toml
├── .gitignore
└── src/
    └── main.rs

A .gitignore fájl gondoskodik arról, hogy a fordítás közben keletkező (nagy méretű, feleslegesen verziózott) fájlok kimaradjanak egy git repóból. A src/main.rs a projekt belépési pontja, a Cargo.toml pedig a projekt "személyi igazolványa" — erről a következő szakaszban lesz szó bővebben.

Megjegyzés

Előretekintés: a src/main.rs pontos tartalmát és azt, hogy mit jelentenek benne az egyes sorok, a következő, "Hello, rustacean!" leckében nézzük végig részletesen. Itt csak azt figyeld meg, hogy ez a fájl automatikusan, kész és fordítható állapotban jön létre:

fn main() {
    println!("Hello, world!");
}

A Cargo.toml anatómiája

A Cargo.toml egy TOML formátumú szövegfájl, amely leírja, mi a projekt, és mire van szüksége. Egy friss projekt Cargo.toml-ja valahogy így néz ki:

[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2024"

[dependencies]

A [package] szekció az alapadatokat tartalmazza: a name a projekt neve (ebből lesz a bináris neve is), a version a saját verziószámod, az edition pedig azt jelzi a fordítónak, hogy a Rust nyelv melyik "kiadását" (2024 edition) használd — ez befolyásolja néhány nyelvi szabály viselkedését, anélkül hogy külön kellene bármit is telepítened.

A [dependencies] szekció alatt sorolod fel, milyen külső csomagokra (ezekről a következő szakaszban lesz szó) van szükséged. Egy friss projektben ez még üres.

Figyelem

A TOML szintaxisa szigorú: egy elgépelt idézőjel is fordítási hibát okoz, még mielőtt bármi Rust kód lefutna. Nézzünk egy hibás példát:

[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2024"

[dependencies]
rand = "0.9

A hiányzó záró idézőjel miatt a cargo build már a manifest beolvasásánál elhasal:

error: failed to parse manifest at `/…/hello_cargo/Cargo.toml`

Caused by:
  TOML parse error at line 8, column 8

build, run és check — mikor melyiket?

Három parancs fedi le a napi munka nagy részét.

A cargo build lefordítja a projektet, és a binárist a target/debug/ mappába teszi:

cargo build

A cargo run ugyanezt csinálja, majd azonnal elindítja is a lefordított programot — ez a leggyakoribb parancs fejlesztés közben:

cargo run

A cargo check viszont nem generál futtatható binárist, csak megvizsgálja, hogy a kód egyáltalán lefordulna-e:

cargo check

Ez sokkal gyorsabb, mint a teljes build, mert kihagyja a végső, gépi kódot előállító lépést. Ha csak azt akarod tudni, hibátlan-e a kódod (például miközben egy szerkesztőben dolgozol), a cargo check-et éri meg gyakran futtatni, és csak a végén cargo run-t, amikor tényleg ki is akarod próbálni a programot.

Tipp

Sok szövegszerkesztő és IDE-bővítmény a háttérben automatikusan cargo check-et futtat minden mentésnél — pont azért, mert ez a legolcsóbb visszajelzés arról, hogy a kód helyes-e.

cargo test alapjai

A cargo test parancs lefuttatja a projektben található teszteket:

cargo test

Egy most létrehozott, még teszt nélküli projektben a kimenet valahogy így néz ki:

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

A Cargo tehát most is lefordítja a projektet, majd megkeresi és lefuttatja az összes tesztet — csak most még nincs egy sem. Azt, hogyan írj saját teszteket, egy későbbi leckében tanulod meg részletesen; itt elég annyit tudni, hogy a cargo test ugyanolyan alapparancs, mint a build vagy a run.

crates.io: a Rust csomagtára

A [dependencies] szekcióba írt csomagok (crate-ek) alapesetben a crates.io-ról érkeznek — ez a Rust közösség központi, nyilvános csomagtára, ahova bárki feltölthet újrafelhasználható kódot. Ha a Cargo.toml-ban megadsz egy függőséget:

[dependencies]
rand = "0.9"

akkor a következő cargo build (vagy cargo run, cargo check) automatikusan letölti a crates.io-ról a rand csomag megfelelő verzióját, lefordítja, és a projektedhez linkeli — mindezt anélkül, hogy neked bármit is kézzel kellene telepítened. Az első ilyen build után a Cargo egy Cargo.lock nevű fájlt is generál, amely rögzíti, pontosan melyik verziók lettek letöltve — ez biztosítja, hogy a projekt más gépen is ugyanazokkal a függőségekkel forduljon.

Próbáld ki!

Hozz létre egy új projektet cargo new probald_ki néven, majd:

  1. futtasd egymás után a cargo check, cargo build és cargo run parancsokat, és figyeld meg, melyik mennyi ideig tart, és mi jelenik meg a target/debug/ mappában;
  2. adj hozzá egy rand = "0.9" sort a [dependencies] alá, és futtasd újra a cargo build-et — nézd meg, mi történik, és mi jelenik meg a Cargo.lock fájlban;
  3. futtasd le a cargo test-et is, és ellenőrizd, hogy a kimenet megegyezik-e a leckében látottal.

Önellenőrzés

Megoldás

Kérdés: Mi a különbség a cargo build és a cargo check között, és mikor melyiket használnád?

A cargo build végigfut a teljes fordítási folyamaton, és futtatható binárist hoz létre a target/ mappában. A cargo check csak azt ellenőrzi, hogy a kód helyes-e, futtatható bináris nélkül — ezért gyorsabb. Fejlesztés közben, gyakori mentésnél a check a praktikusabb, futtatáshoz viszont build vagy run szükséges.

Megoldás

Kérdés: Honnan tudja a Cargo, hogy melyik verziójú függőséget töltse le?

A Cargo.toml [dependencies] szekciójában megadott verziómegkötés (pl. "0.9") alapján választja ki az adott csomag legfrissebb, a megkötésnek megfelelő verzióját a crates.io-ról, majd ezt rögzíti a Cargo.lock fájlban, hogy később mindig pontosan ugyanazt a verziót használja.

Megoldás

Kérdés: Mi történik, ha lefuttatod a cargo test parancsot egy olyan projekten, amelyben még nincs egyetlen teszt sem?

A Cargo lefordítja a projektet, majd megkeresi a teszteket. Mivel nincs egy sem, a kimenet "running 0 tests" lesz, és az eredmény "ok" státuszú, 0 sikeres és 0 sikertelen teszttel — nem hibáz, csak jelzi, hogy nincs mit futtatni.

Összefoglaló és mi jön legközelebb

  • A Cargo a Rust build-eszköze és csomagkezelője, amit a rustup automatikusan telepít a rustc mellé.
  • A cargo new egy azonnal fordítható projektstruktúrát generál, Cargo.toml és src/main.rs fájlokkal.
  • A Cargo.toml tartalmazza a projekt metaadatait ([package]) és a függőségek listáját ([dependencies]).
  • A cargo build lefordít, a cargo run lefordít és futtat, a cargo check csak gyorsan ellenőriz — a cargo test pedig a projekt tesztjeit futtatja le.
  • A crates.io a Rust közösségi csomagtára, ahonnan a Cargo automatikusan letölti a [dependencies]-ben felsorolt csomagokat.

A következő leckében ("Hello, rustacean!") végre alaposan megnézzük, mit is jelentenek a src/main.rs fájlban látott sorok — mi az a fn main, és mit csinál a println!.

További olvasmány: