I. Les bases de la programmation en Rust
13. Cargo
Rust possède un gestionnaire de paquets : Cargo. Il permet aussi de grandement faciliter la gestion de la compilation (en permettant de faire des builds personnalisées notamment) ainsi que des dépendances externes. Toutes les informations que je vais vous donner dans ce chapitre peuvent être retrouvées ici (en anglais). N'hésitez pas à y faire un tour !
Pour commencer un projet avec Cargo, rien de plus facile :
cargo new mon_nouveau_project
Un nouveau dossier s'appelant mon_nouveau_project sera créé :
- mon_nouveau_project
|
|- Cargo.toml
|- .gitignore
|- src/
Le fichier Cargo.toml à la racine de votre projet devrait contenir :
[package]
name = "mon_nouveau_project"
version = "0.0.1"
authors = ["Votre nom <vous@exemple.com>"]
Tous les fichiers sources (.rs normalement) doivent être placés dans un sous-dossier appelé src. C’est à dire qu'on va avoir un fichier main.rs dans le dossier src :
Runfn main() {
println!("Début du projet");
}
Maintenant pour compiler le projet, il vous suffit de faire :
cargo build
L'exécutable sera généré dans le dossier target/debug/. Pour le lancer :
$ ./target/debug/mon_nouveau_project
Début du projet
Si vous voulez compiler et lancer l'exécutable tout de suite après, vous pouvez utiliser la commande run :
$ cargo run
Fresh mon_nouveau_project v0.0.1 (file:///path/to/project/mon_nouveau_project)
Running `target/debug/mon_nouveau_project`
Début du projet
Par défaut, cargo compile en mode debug. Les performances sont BEAUCOUP plus faibles qu'en mode release, faites donc bien attention à vérifier que vous n'avez pas compilé en mode debug dans un premier temps si vous avez des problèmes de performance. Si vous souhaitez compiler en mode release, il vous faudra passer l'option "--release" :
cargo build --release
Bien évidemment, l'exécutable généré se trouvera dans le dossier target/release.
Cela fonctionne de la même façon pour lancer l'exécution :
cargo run --release
Gérer les dépendances
Si vous voulez utiliser une bibliothèque externe, cargo peut le gérer pour vous. Il y a plusieurs façons de faire :
- Soit la bibliothèque est disponible sur crates.io, et dans ce cas il vous suffira de préciser la version que vous désirez.
- Soit elle ne l'est pas : dans ce cas vous pourrez indiquer son chemin d'accès si elle est présente sur votre ordinateur, ou bien vous pourrez donner l'adresse de son dépôt git.
Avant d'aller plus loin, il est important de noter : les paquets sont appelés des crates en Rust ("cagette" en français), d'où le nom "crates.io". Il sera donc fréquent que ce mot soit utilisé à la place de "bibliothèque".
Par exemple, vous voulez utiliser la crate sysinfo, elle est disponible sur crates.io ici, donc pas de souci :
[package]
name = "mon_nouveau_project"
version = "0.0.1"
authors = ["Votre nom <vous@exemple.com>"]
[dependencies]
sysinfo = "0.27.0"
Nous avons donc ajouté sysinfo comme dépendance à notre projet. Détail important : à chaque fois que vous ajoutez/modifiez/supprimez une dépendance, il vous faudra relancer cargo build pour que ce soit pris en compte ! D'ailleurs, si vous souhaitez mettre à jour les crates que vous utilisez, il vous faudra utiliser la commande :
cargo update
Je ne rentrerai pas plus dans les détails concernant l'utilisation d'une bibliothèque externe ici car le chapitre suivant traite ce sujet.
Si vous voulez utiliser une version précise (antérieure) de sysinfo , vous pouvez la préciser comme ceci :
[dependencies]
sysinfo = "0.18.0"
Il est cependant possible de faire des choses un peu plus intéressantes avec la gestion des versions. Par exemple, vous pouvez autoriser certaines versions de la crate :
Le "^" permet notamment :
^1.2.3 := >=1.2.3 <2.0.0
^0.2.3 := >=0.2.3 <0.3.0
^0.0.3 := >=0.0.3 <0.0.4
^0.0 := >=0.0.0 <0.1.0
^0 := >=0.0.0 <1.0.0
Le "~" permet :
~1.2.3 := >=1.2.3 <1.3.0
~1.2 := >=1.2.0 <1.3.0
~1 := >=1.0.0 <2.0.0
Le "*" permet :
* := >=0.0.0
1.* := >=1.0.0 <2.0.0
1.2.* := >=1.2.0 <1.3.0
Et enfin les symboles d'(in)égalité permettent :
>= 1.2.0
> 1
< 2
= 1.2.3
Il est possible de mettre plusieurs exigences en les séparant avec une virgule : >= 1.2, < 1.5.
.
Maintenant regardons comment ajouter une dépendance à une crate qui n'est pas sur crates.io (ou qui y est mais pour une raison ou pour une autre, vous ne voulez pas passer par elle).
[package]
name = "mon_nouveau_project"
version = "0.0.1"
authors = ["Votre nom <vous@exemple.com>"]
[dependencies.sysinfo]
git = "https://github.com/GuillaumeGomez/sysinfo"
Ici nous avons indiqué que la crate sysinfo se trouvait à cette adresse de github. Il est aussi possible que vous l'ayez téléchargé, dans ce cas il va vous falloir indiquer où elle se trouve :
[dependencies.sysinfo]
path = "chemin/vers/sysinfo"
Voici en gros à quoi ressemblerait un fichier cargo :
[package]
name = "mon_nouveau_project"
version = "0.0.1"
authors = ["Votre nom <vous@exemple.com>"]
[dependencies.sysinfo]
git = "https://github.com/GuillaumeGomez/sysinfo"
[dependencies.gsl]
version = "0.0.1" # optionnel
path = "path/vers/gsl"
[dependencies]
sdl = "0.3"
cactus = "0.2.3"
Publier une crate sur crates.io
Vous avez fait une crate et vous avez envie de la mettre à disposition des autres développeurs ? Pas de soucis ! Tout d'abord, il va vous falloir un compte sur crates.io (pour le moment il semblerait qu'il faille obligatoirement un compte sur github pour pouvoir se connecter sur crates.io). Une fois que c'est fait, allez sur la page de votre compte. Vous devriez voir ça écrit dessus :
cargo login abcdefghijklmnopqrstuvwxyz012345
Exécutez cette commande sur votre ordinateur pour que cargo puisse vous identifier. IMPORTANT : CETTE CLEF NE DOIT PAS ETRE TRANSMISE !!! Si jamais elle venait à être divulguée à quelqu'un d'autre que vous-même, supprimez-la et régénérez-en une nouvelle aussitôt !
Regardons maintenant les metadata que nous pouvons indiquer pour permettre "d'identifier" notre crate :
- description : Brève description de la crate.
- documentation : URL vers la page où se trouve la documentation de votre crate.
- homepage : URL vers la page de présentation de votre crate.
- repository : URL vers le dépôt où se trouve le code source de votre crate.
- readme : Chemin de l'emplacement du fichier README (relatif au fichier Cargo.toml).
- keywords : Mots-clés permettant pour catégoriser votre crate sur crates.io.
- license : Licence(s) de votre crate. On peut en mettre plusieurs en les séparant avec un '/'. La liste des licences disponibles se trouve ici.
- license-file : Si la licence que vous cherchez n'est pas dans la liste de celles disponibles, vous pouvez donner le chemin du fichier contenant la vôtre (relatif au fichier Cargo.toml).
Je vais vous donner ici le contenu (un peu raccourci) du fichier Cargo.toml de la crate sysinfo pour que vous ayez un exemple :
[package]
name = "sysinfo"
version = "0.27.0"
authors = ["Guillaume Gomez <guillaume1.gomez@gmail.com>"]
description = "Library to get system information such as processes, CPUs, disks, components and networks"
repository = "https://github.com/GuillaumeGomez/sysinfo"
license = "MIT"
readme = "README.md"
rust-version = "1.59"
exclude = ["/test-unknown"]
categories = ["filesystem", "os", "api-bindings"]
build = "build.rs"
edition = "2018"
[dependencies]
cfg-if = "1.0"
rayon = { version = "^1.5.1", optional = true }
[features]
default = ["multithread"]
multithread = ["rayon"]
Voilà ! Comme vous pouvez le voir, il y a aussi une option [features]
. Elle permet dans le cas de sysinfo de désactiver le multi-threading. Vous pouvez utiliser les features comme la gestion de version d'une bibliothèque C. Par-exemple, seulement la version 1.0 est "activée" par défaut, et si l'utilisateur utilise une version plus récente il devra activer la feature correspondante (v1_1
ou v1_2
par example). Il est important de noter cependant qu'il n'y a rien de normalisé à ce niveau donc à vous de regarder quand vous utilisez une crate si elles possèdent plus de features qui pourraient vous intéresser.
Nous voici enfin à la dernière étape : publier la crate. ATTENTION : une crate publiée ne peut pas être supprimée ! Il n'y a pas de limite non plus sur le nombre de versions qui peuvent être publiées.
Le nom sous lequel votre crate sera publiée est celui donné par la metadonnée name :
[package]
name = "super"
Si une crate portant le nom "super" est déjà publiée sur crates.io, vous ne pourrez rien y faire, il faudra trouver un autre nom. Une fois que tout est prêt, utilisez la commande :
cargo publish
Et voilà, votre crate est maintenant visible sur crates.io et peut être utilisée par tout le monde !
Si vous voulez faire un tour plus complet de ce que Cargo permet de faire, je vous recommande encore une fois d'aller lire le Cargo book (en anglais).