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

Hello, Cargo!

Cargo è il sistema di compilazione e il gestore di pacchetti di Rust. La maggior parte dei Rustaceani utilizza questo strumento per gestire i propri progetti Rust perché Cargo gestisce molte attività al posto tuo, come la compilazione del codice, il download delle librerie da cui dipende il tuo codice e la compilazione di tali librerie (chiamiamo le librerie di cui il tuo codice ha bisogno dipendenze)

I programmi Rust più semplici, come quello che abbiamo scritto finora, non hanno dipendenze. Se avessimo costruito il progetto “Hello, world!” con Cargo, questo avrebbe utilizzato solo la parte di Cargo che si occupa della costruzione del codice. Man mano che scriverai programmi Rust più complessi, aggiungerai delle dipendenze e se inizierai un progetto utilizzando Cargo, sarà molto più facile aggiungere dipendenze.

Poiché la stragrande maggioranza dei progetti Rust utilizza Cargo, il resto di questo libro presuppone che anche tu stia utilizzando Cargo. Cargo viene installato insieme a Rust se hai utilizzato l’installazione di cui si parla nella sezione “Installazione”. Se hai installato Rust in altro modo, controlla se Cargo è installato inserendo quanto segue nel tuo terminale:

$ cargo --version

Se viene visualizzato un numero di versione, allora è fatta! Se viene visualizzato un errore, come ad esempio comando non trovato, consulta la documentazione relativa al tuo metodo di installazione per determinare come installare Cargo separatamente.

Creare un progetto con Cargo

Creiamo un nuovo progetto utilizzando Cargo e vediamo come si differenzia dal nostro progetto originale “Hello, world!”. Torna alla tua cartella progetti (o dove hai deciso di memorizzare il tuo codice). Poi, su qualsiasi sistema operativo, esegui il seguente comando:

$ cargo new hello_cargo
$ cd hello_cargo

Il primo comando crea una nuova directory e un nuovo progetto chiamato hello_cargo. Abbiamo chiamato il nostro progetto hello_cargo e Cargo crea i suoi file in una directory con lo stesso nome.

Vai nella directory hello_cargo ed elenca i file. Vedrai che Cargo ha generato due file e una directory per noi: un file Cargo.toml e una directory src con un file main.rs al suo interno.

Ha anche inizializzato un nuovo repository Git insieme a un file .gitignore. I file Git non verranno generati se esegui cargo new all’interno di un repository Git esistente; puoi annullare questo comportamento utilizzando cargo new --vcs=git.

Nota: Git è un diffuso software di controllo di versione distribuito. Puoi modificare cargo new per utilizzare un altro sistema di controllo di versione o nessun sistema di controllo di versioni utilizzando il flag --vcs. Esegui cargo new --help per vedere le opzioni disponibili.

Apri Cargo.toml nell’editor di testo che preferisci. Dovrebbe assomigliare al codice del Listato 1-2.

File: Cargo.toml
[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2024"

[dependencies]
Listato 1-2: Contenuto di Cargo.toml generato da cargo new

Questo file è nel formato TOML (Tom’s Obvious, Minimal Language), che è il formato di configurazione di Cargo.

La prima riga, [package], è un’intestazione di sezione che indica che le dichiarazioni seguenti stanno configurando un pacchetto. Man mano che aggiungeremo altre informazioni a questo file, aggiungeremo altre sezioni.

Le tre righe successive definiscono le informazioni di configurazione di cui Cargo ha bisogno per compilare il tuo programma: il nome, la versione e l’edizione di Rust da utilizzare. Parleremo della chiave edition in Appendice E.

L’ultima riga, [dependencies], è l’inizio di una sezione in cui puoi elencare tutte le dipendenze del tuo progetto. In Rust, i pacchetti di codice sono chiamati crates (ndt: inteso come cassetta, cestino…). Non avremo bisogno di altri crates per questo progetto, ma lo faremo nel primo progetto del Capitolo 2, quindi useremo questa sezione di dipendenze.

Ora apri src/main.rs e dai un’occhiata:

File: src/main.rs

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

Cargo ha generato per te un programma “Hello, world!”, proprio come quello che abbiamo scritto nel Listato 1-1! Finora, le differenze tra il nostro progetto e quello generato da Cargo sono che Cargo ha inserito il codice nella directory src e che c’è un file di configurazione Cargo.toml nella directory principale.

Cargo si aspetta che i tuoi file sorgente si trovino all’interno della directory src. La directory principale del progetto è solo per i file README, le informazioni sulla licenza, i file di configurazione e tutto ciò che non riguarda il tuo codice. L’utilizzo di Cargo ti aiuta a organizzare i tuoi progetti: c’è un posto per ogni cosa e ogni cosa è al suo posto.

If you started a project that doesn’t use Cargo, as we did with the “Hello, world!” project, you can convert it to a project that does use Cargo. Move the project code into the src directory and create an appropriate Cargo.toml file. One easy way to get that Cargo.toml file is to run cargo init, which will create it for you automatically. Se hai iniziato un progetto che non utilizza Cargo, come abbiamo fatto con il progetto “Hello, world!”, puoi convertirlo in un progetto che utilizza Cargo. Sposta il codice del progetto nella directory src e crea un file Cargo.toml appropriato. Un modo semplice per ottenere il file Cargo.toml è eseguire cargo init, che lo creerà automaticamente.

Costruire e eseguire un progetto Cargo

Ora vediamo cosa cambia quando costruiamo ed eseguiamo il programma “Hello, world!” con Cargo! Dalla cartella hello_cargo, costruisci il tuo progetto inserendo il seguente comando:

$ cargo build
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs

Questo comando crea un file eseguibile in target/debug/hello_cargo (o target\debug\hello_cargo.exe_ su Windows) anziché nella tua directory corrente. Poiché la compilazione predefinita è una compilazione di debug, Cargo mette il binario in una directory chiamata debug. Puoi eseguire l’eseguibile con questo comando:

$ ./target/debug/hello_cargo # o .\target\debug\hello_cargo.exe su Windows
Hello, world!

Se tutto è andato bene, Hello, world! dovrebbe essere stampato sul terminale. L’esecuzione di cargo build per la prima volta fa sì che Cargo crei anche un nuovo file nella directory principale: Cargo.lock. Questo file tiene traccia delle versioni esatte delle dipendenze nel tuo progetto. Questo progetto non ha dipendenze, quindi il file è un po’ scarno. Non dovrai mai modificare questo file manualmente; Cargo gestisce il suo contenuto per te.

Abbiamo appena costruito un progetto con cargo build e lo abbiamo eseguito con ./target/debug/hello_cargo, ma possiamo anche usare cargo run per compilare il codice e poi eseguire l’eseguibile risultante con un solo comando:

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/hello_cargo`
Hello, world!

Utilizzare cargo run è più comodo che doversi ricordare di eseguire cargo build e poi utilizzare l’intero percorso del binario, quindi la maggior parte degli sviluppatori utilizza cargo run.

Nota che questa volta non abbiamo visto l’output che indicava che Cargo stava compilando hello_cargo. Cargo ha capito che i file non erano cambiati, quindi non ha ricostruito ma ha semplicemente eseguito il binario. Se avessi modificato il codice sorgente, Cargo avrebbe ricostruito il progetto prima di eseguirlo e avresti visto questo output:

$ 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 offre anche un comando chiamato cargo check, che controlla rapidamente il tuo codice per assicurarsi che venga compilato ma che non produce un eseguibile:

$ cargo check
   Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs

E perché non dovresti volere un eseguibile? Spesso, cargo check è molto più veloce di cargo build perché salta il passaggio della produzione di un eseguibile. Se controlli continuamente il tuo lavoro mentre scrivi il codice, l’uso di cargo check accelererà il processo di sapere se il tuo progetto è privo di errori e compilabile! Per questo motivo, molti Rustaceani eseguono cargo check periodicamente mentre scrivono il loro programma per assicurarsi che si compili. Poi eseguono cargo build quando sono pronti a creare l’eseguibile.

Ricapitoliamo quello che abbiamo imparato finora su Cargo:

  • Possiamo creare un progetto utilizzando cargo new.
  • Possiamo costruire un progetto utilizzando cargo build.
  • Possiamo costruire ed eseguire un progetto in un unico passaggio utilizzando cargo run.
  • Possiamo costruire un progetto senza produrre un binario per controllare gli errori utilizzando cargo check.
  • Invece di salvare il risultato della compilazione nella stessa directory del nostro codice, Cargo lo salva nella directory target/debug.

Un ulteriore vantaggio dell’utilizzo di Cargo è che i comandi sono gli stessi indipendentemente dal sistema operativo su cui stai lavorando. Quindi, a questo punto, non forniremo più istruzioni specifiche per Linux e macOS rispetto a Windows.

Costruire per il Rilascio

Quando il tuo progetto è finalmente pronto per essere rilasciato, puoi usare cargo build --release per compilarlo con le ottimizzazioni. Questo comando creerà un eseguibile in target/release invece che in target/debug. Le ottimizzazioni rendono il tuo codice Rust più veloce, ma attivarle allunga i tempi di compilazione del tuo programma. Per questo motivo esistono due profili diversi: uno per lo sviluppo, quando vuoi ricostruire rapidamente e spesso, e un altro per la creazione del programma finale che darai a un utente e che non sarà ricostruito più volte e che funzionerà il più velocemente possibile. Se vuoi fare un benchmark del tempo di esecuzione del tuo codice, assicurati di eseguire cargo build --release e di fare il benchmark con l’eseguibile in target/release.

Cargo come convenzione

Con i progetti semplici, Cargo non offre molti vantaggi rispetto all’uso di rustc, ma si dimostrerà utile quando i tuoi programmi diventeranno più complessi. Quando i programmi diventano più file o hanno bisogno di una dipendenza, è molto più facile lasciare che Cargo coordini la compilazione.

Anche se il progetto hello_cargo è semplice, ora utilizza gran parte degli strumenti che userai nel resto della tua carriera in Rust. Infatti, per lavorare su qualsiasi progetto esistente, puoi usare i seguenti comandi per verificare il codice usando Git, passare alla directory del progetto e compilare:

$ git clone example.org/un_progetto_nuovo
$ cd un_progetto_nuovo
$ cargo build

Per maggiori informazioni su Cargo, consulta la documentazione.

Riassunto

Sei già partito alla grande nel tuo viaggio assieme a Rust! In questo capitolo hai imparato a..:

  • Installare l’ultima versione stabile di Rust usando rustup
  • Aggiornare a una versione più recente di Rust
  • Aprire la documentazione installata localmente
  • Scrivere ed eseguire un programma “Hello, world!” usando direttamente rustc
  • Creare ed eseguire un nuovo progetto usando le convenzioni di Cargo

Questo è un ottimo momento per costruire un programma più sostanzioso per abituarsi a leggere e scrivere codice in Rust. Quindi, nel Capitolo 2, costruiremo un programma di gioco di indovinelli. Se invece preferisci iniziare imparando come funzionano in Rust alcuni concetti base della programmazione, consulta il Capitolo 3 e poi ritorna al Capitolo 2.