Hello, Cargo!
Cargo est le système de compilation et de gestion de paquets de Rust. La plupart des Rustacés utilisent cet outil pour gérer les projets Rust, car Cargo s'occupe de nombreuses tâches pour vous, comme compiler votre code, télécharger les bibliothèques dont votre code dépend, et compiler ces bibliothèques. (On appelle dépendance une bibliothèque nécessaire pour votre code.)
Des programmes Rust très simples, comme le petit que nous avons écrit précédemment, n'ont pas de dépendance. Donc si nous avions compilé le projet “Hello, world!” avec Cargo, cela n'aurait fait appel qu'à la fonctionnalité de Cargo qui s'occupe de la compilation de votre code. Quand vous écrirez des programmes Rust plus complexes, vous ajouterez des dépendances, et si vous créez un projet en utilisant Cargo, l'ajout des dépendances sera plus facile à faire.
Comme la large majorité des projets Rust utilisent Cargo, la suite de ce livre va supposer que vous utilisez aussi Cargo. Cargo s'installe avec Rust si vous avez utilisé l'installateur officiel présenté dans la section “Installation”. Si vous avez installé Rust autrement, vérifiez que Cargo est installé en utilisant la commande suivante dans votre terminal :
$ cargo --version
Si vous voyez un numéro de version, c'est qu'il est installé ! Si vous voyez une
erreur comme Commande non trouvée
(ou command not found
), alors consultez la
documentation de votre méthode d'installation pour savoir comment installer
séparément Cargo.
Créer un projet avec Cargo
Créons un nouveau projet en utilisant Cargo et analysons les différences avec notre projet initial “Hello, world!”. Retournez dans votre dossier projects (ou là où vous avez décidé d'enregistrer votre code). Ensuite, sur n'importe quel système d'exploitation, lancez les commandes suivantes :
$ cargo new hello_cargo
$ cd hello_cargo
La première commande a crée un nouveau dossier appelé hello_cargo. Nous avons appelé notre projet hello_cargo, et Cargo crée ses fichiers dans un dossier avec le même nom.
Rendez-vous dans le dossier hello_cargo et afficher la liste des fichiers. Vous constaterez que Cargo a généré deux fichiers et un dossier pour nous : un fichier Cargo.toml et un dossier src avec un fichier main.rs à l'intérieur.
Il a aussi créé un nouveau dépôt Git ainsi qu'un fichier .gitignore. Les
fichiers de Git ne seront pas générés si vous lancez cargo new
au sein d'un
dépôt Git ; vous pouvez désactiver ce comportement temporairement en utilisant
cargo new --vcs=git
.
Note : Git est un système de gestion de versions très répandu. Vous pouvez changer
cargo new
pour utiliser un autre système de gestion de versions ou ne pas en utiliser du tout en écrivant le drapeau--vcs
. Lancezcargo new --help
pour en savoir plus sur les options disponibles.
Ouvrez Cargo.toml dans votre éditeur de texte favori. Son contenu devrait être similaire au code dans l'encart 1-2.
Fichier : Cargo.toml
[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"
[dependencies]
Ce fichier est au format TOML (Tom’s Obvious, Minimal Language), qui est le format de configuration de Cargo.
La première ligne, [package]
, est un en-tête de section qui indique que les
instructions suivantes configurent un paquet. Au fur et à mesure que nous
ajouterons plus de détails à ce fichier, nous ajouterons des sections
supplémentaires.
Les trois lignes suivantes définissent les informations de configuration dont
Cargo a besoin pour compiler votre programme : le nom, la version, et l'édition
de Rust à utiliser. Nous aborderons la clé edition
dans
l'Annexe E.
La dernière ligne, [dependencies]
, est le début d'une section qui vous permet
de lister les dépendances de votre projet. Dans Rust, les paquets de code sont
désignés sous le nom de crates. Nous n'allons pas utiliser de crate pour ce
projet, mais nous le ferons pour le premier projet au chapitre 2 ; nous
utiliserons alors cette section à ce moment-là.
Maintenant, ouvrez src/main.rs et jetez-y un coup d'œil :
Fichier : src/main.rs
fn main() { println!("Hello, world!"); }
Cargo a généré un programme “Hello, world!” pour vous, exactement comme celui que nous avons écrit dans l'encart 1-1 ! Pour le moment, les seules différences entre notre projet précédent et le projet que Cargo a généré sont que Cargo a placé le code dans le dossier src, et que nous avons un fichier de configuration Cargo.toml à la racine du dossier projet.
Cargo prévoit de stocker vos fichiers sources dans le dossier src. Le dossier parent est là uniquement pour les fichiers README, pour les informations à propos de la licence, pour les fichiers de configuration et tout ce qui n'est pas directement relié à votre code. Utiliser Cargo vous aide à structurer vos projets. Il y a un endroit pour tout, et tout est à sa place.
Si vous commencez un projet sans utiliser Cargo, comme nous l'avons fait avec le projet “Hello, world!”, vous pouvez le transformer en projet qui utilise Cargo. Déplacez le code de votre projet dans un dossier src et créez un fichier Cargo.toml adéquat.
Compiler et exécuter un projet Cargo
Maintenant, regardons ce qu'il y a de différent quand nous compilons et exécutons le programme “Hello, world!” avec Cargo ! À l'intérieur de votre dossier hello_cargo, compilez votre projet en utilisant la commande suivante :
$ cargo build
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs
Cette commande crée un fichier exécutable dans target/debug/hello_cargo (ou target\debug\hello_cargo.exe sous Windows) plutôt que de le déposer dans votre dossier courant. Vous pouvez lancer l'exécutable avec cette commande :
$ ./target/debug/hello_cargo # ou .\target\debug\hello_cargo.exe sous Windows
Hello, world!
Si tout s'est bien passé, Hello, world!
devrait s'afficher dans le terminal.
Lancer cargo build
pour la première fois devrait aussi mener Cargo à créer
un nouveau fichier à la racine du dossier projet : Cargo.lock. Ce fichier
garde une trace des versions exactes des dépendances de votre
projet. Ce projet n'a pas de dépendance, donc le fichier est un peu vide. Vous
n'aurez jamais besoin de changer ce fichier manuellement ; Cargo va gérer son
contenu pour vous.
Nous venons de compiler un projet avec cargo build
avant de l'exécuter avec
./target/debug/hello_cargo
, mais nous pouvons aussi utiliser cargo run
pour
compiler le code et ensuite lancer l'exécutable dans une seule et même
commande :
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/hello_cargo`
Hello, world!
Notez que cette fois-ci, nous ne voyons pas de messages indiquant que Cargo a
compilé hello_cargo
. Cargo a détecté que les fichiers n'avaient pas changé,
donc il a juste exécuté le binaire. Si vous aviez modifié votre code source,
Cargo aurait recompilé le projet avant de le lancer, et vous auriez eu les
messages suivants :
$ 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 fournit aussi une commande appelée cargo check
. Elle vérifie rapidement
votre code pour s'assurer qu'il est compilable, mais ne produit pas
d'exécutable :
$ cargo check
Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
Dans quel cas n'aurions-nous pas besoin d'un exécutable ? Parfois, cargo check
est bien plus rapide que cargo build
, car il saute l'étape de création de
l'exécutable. Si vous vérifiez votre travail continuellement pendant que vous
écrivez votre code, utiliser cargo check
accélèrera le processus ! C'est
pourquoi de nombreux Rustacés utilisent périodiquement cargo check
quand ils
écrivent leur programme afin de s'assurer qu'il compile. Ensuite, ils lancent
cargo build
quand ils sont prêts à utiliser l'exécutable.
Récapitulons ce que nous avons appris sur Cargo :
- Nous pouvons créer un projet en utilisant
cargo new
. - Nous pouvons compiler un projet en utilisant
cargo build
. - Nous pouvons compiler puis exécuter un projet en une seule fois en utilisant
cargo run
. - Nous pouvons compiler un projet sans produire de binaire afin de vérifier
l'existance d'erreurs en utilisant
cargo check
. - Au lieu d'enregistrer le résultat de la compilation dans le même dossier que votre code, Cargo l'enregistre dans le dossier target/debug.
Un autre avantage d'utiliser Cargo est que les commandes sont les mêmes peu importe le système d'exploitation que vous utilisez. Donc à partir de maintenant, nous n'allons plus faire d'opérations spécifiques à Linux et macOS par rapport à Windows.
Compiler pour diffuser
Quand votre projet est finalement prêt à être diffusé, vous pouvez utiliser
cargo build --release
pour le compiler en l'optimisant. Cette commande va
créer un exécutable dans target/release au lieu de target/debug. Ces
optimisations rendent votre code Rust plus rapide à exécuter, mais l'utiliser
rallonge le temps de compilation de votre programme. C'est pourquoi il y a deux
différents profils : un pour le développement, quand vous voulez recompiler
rapidement et souvent, et un autre pour compiler le programme final qui sera
livré à un utilisateur, qui n'aura pas besoin d'être recompilé à plusieurs
reprises et qui s'exécutera aussi vite que possible. Si vous évaluez le temps
d'exécution de votre code, assurez-vous de lancer cargo build --release
et
d'utiliser l'exécutable dans target/release pour vos bancs de test.
Cargo comme convention
Pour des projets simples, Cargo n'apporte pas grand-chose par rapport à rustc
,
mais il vous montrera son intérêt au fur et à mesure
que vos programmes deviendront plus complexes. Avec des projets complexes
composés de plusieurs crates, il est plus facile de laisser Cargo prendre en
charge la coordination de la compilation.
Même si le projet hello_cargo
est simple, il utilise maintenant une grande
partie de l'outillage que vous rencontrerez dans votre carrière avec Rust. En
effet, pour travailler sur n'importe quel projet Rust existant, vous n'avez
qu'à saisir les commandes suivantes pour télécharger le code avec Git, vous
déplacer dans le dossier projet et compiler :
$ git clone example.org/projet_quelconque
$ cd projet_quelconque
$ cargo build
Pour plus d'informations à propos de Cargo, vous pouvez consulter sa documentation.
Résumé
Vous êtes déjà bien lancé dans votre périple avec Rust ! Dans ce chapitre, vous avez appris comment :
- Installer la dernière version stable de Rust en utilisant
rustup
- Mettre à jour Rust vers une nouvelle version
- Ouvrir la documentation installée en local
- Écrire et exécuter un programme “Hello, world!” en utilisant directement
rustc
- Créer et exécuter un nouveau projet en utilisant les conventions de Cargo
C'est le moment idéal pour construire un programme plus ambitieux pour s'habituer à lire et écrire du code Rust. Donc, au chapitre 2, nous allons écrire un programme de jeu de devinettes. Si vous préférez commencer par apprendre comment les principes de programmation de base fonctionnent avec Rust, rendez-vous au chapitre 3, puis revenez au chapitre 2.