Rust

Any donation is very welcome
Fork me on GitHub

I. Les bases de la programmation en Rust

11. Cargo

Rust possède un gestionnaire de paquets : Cargo. Il permet 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 project avec Cargo, rien de plus facile :

> cargo new mon_nouveau_project

Un nouveau dossier s'appelant mon_nouveau_project sera crée :

 - 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

Et voilà ! 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

Et voilà !

Par défaut, cargo compile en mode debug. Les performances sont BEAUCOUP plus faibles qu'en mode release, faites 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, soit vous pourrez donner son adresse github.

Par exemple, vous voulez utiliser la bibliothèque GTK+, 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]
gtk = "0.3.0"

Nous avons donc ajouté gtk 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 bibliothèques 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 de ce sujet.

Si vous voulez utiliser une version précise (antérieure) de gtk , vous pouvez la préciser comme ceci :

[dependencies]
gtk = "0.0.2"

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 bibliothèque :

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 bibliothèque 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.gtk]
git = "https://github.com/gtk-rs/gtk"

Ici nous avons indiqué que la bibliothèque gtk 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.gtk]
path = "chemin/vers/gtk"

Voici en gros à quoi ressemblerait un gros fichier cargo :

[package]
name = "mon_nouveau_project"
version = "0.0.1"
authors = ["Votre nom <vous@exemple.com>"]

[dependencies.gtk]
git = "https://github.com/gtk-rs/gtk"

[dependencies.gsl]
version = "0.0.1" # optionnel
path = "path/vers/gsl"

[dependencies]
sdl = "0.3"
cactus = "0.2.3"

Publier une bibliothèque sur crates.io

Vous avez fait une bibliothèque 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 bibliothèque :

  • description : Brève description de la bibliothèque.
  • documentation : URL vers la page où se trouve la documentation de votre bibliothèque.
  • homepage : URL vers la page de présentation de votre bibliothèque.
  • repository : URL vers le dépôt où se trouve le code source de votre bibliothèque.
  • readme : Chemin de l'emplacement du fichier README (relatif au fichier Cargo.toml).
  • keywords : Mots-clés permettant pour catégoriser votre bibliothèque.
  • license : Licence(s) de votre bibliothèque. 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 votre (relatif au fichier Cargo.toml).

Je vais vous donner ici le contenu du fichier Cargo.toml de la bibliothèque GTK pour que vous ayez un exemple :

[package]
name = "gtk"
version = "0.0.2"
authors = ["The Gtk-rs Project Developers"]

description = "Rust bindings for the GTK+ library"
repository = "https://github.com/rust-gnome/gtk"
license = "MIT"
homepage = "https://github.com/rust-gnome/gtk"
documentation = "https://github.com/rust-gnome/gtk"

readme = "README.md"

keywords = ["gtk", "gnome", "GUI"]

[lib]
name = "gtk"

[features]
default = ["gtk_3_6"]
gtk_3_4 = ["gtk-sys/gtk_3_4", "gdk/gdk_3_4"]
gtk_3_6 = ["gtk-sys/gtk_3_6", "gdk/gdk_3_6", "gtk_3_4"]
gtk_3_8 = ["gtk-sys/gtk_3_8", "gdk/gdk_3_8", "gtk_3_6"]
gtk_3_10 = ["gtk-sys/gtk_3_10", "gdk/gdk_3_10", "cairo-rs/cairo_1_12", "gtk_3_8"]
gtk_3_12 = ["gtk-sys/gtk_3_12", "gdk/gdk_3_12", "gtk_3_10"]
gtk_3_14 = ["gtk-sys/gtk_3_14", "gdk/gdk_3_14", "gtk_3_12"]

[dependencies]
libc = "0.1"
gtk-sys = "^0"
glib = "^0"
glib-sys = "^0"
gdk-sys = "^0"
gdk = "^0"
pango-sys = "^0"
pango = "^0"
cairo-sys-rs = "^0"
cairo-rs = "^0"

Voilà ! Comme vous pouvez le voir, il y a aussi une option [features]. Elle permet dans le cas de GTK de faire une compilation conditionnelle dépendant de la version que vous possédez sur votre ordinateur. Vous ne pouvez par exemple pas utiliser du code de la version 3.12 si vous avez une version 3.4.

Nous voilà enfin à la dernière étape : publier la bibliothèque. ATTENTION : une bibliothèque 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 bibliothèque sera publiée est celui donné par la metadonnée name :

[package]
name = "super"

Si une bibliothèque 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 bibliothèque 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).