Při vývoji aplikací v moderním programovacím jazyce Rust je možné ke správě projektů přistupovat různým způsobem. Někteří programátoři mohou dávat přednost použití vlastních skriptů určených pro překlad a spouštění projektů, další vývojáři mohou naopak použít například možnosti nabízené klasickým nástrojem make (soubory Makefile). V současnosti je ovšem, alespoň ve většině případů, mnohem lepší a současně i jednodušší využít služeb specializovaného a současně i velmi snadno použitelného správce projektů, který se jmenuje Cargo.

Obsah

1. Cargo: správce projektů a balíčků pro programovací jazyk Rust

2. Základní vlastnosti a možnosti nabízené nástrojem Cargo

3. Vytvoření nového projektu

4. Struktura adresáře s projektem

5. Projektové soubory

6. Překlad projektu a spuštění výsledného binárního souboru

7. Spuštění jednotkových testů

8. Příprava binárních souborů pro distribuci

9. Vyčištění projektu – odstranění pracovních souborů

10. Přidání knihovny používané projektem

11. Vyhledání vhodné knihovny

12. Stažení všech závislostí

13. Spuštění projektu a lokální instalace projektu

14. Repositář s demonstračními projekty

15. Odkazy na Internetu

1. Cargo: správce projektů a balíčků pro programovací jazyk Rust

K poměrně velkému množství v současnosti používaných programovacích jazyků existují specializované nástroje určené pro správu projektů a/nebo pro instalaci balíčků evidovaných v nějakém centrálním repositáři. Připomeňme si například Maven pro Javu, pip pro Python, RubyGems pro programovací jazyk Ruby či npm pro JavaScriptové projekty. Podobný nástroj existuje i pro programovací jazyk Rust. Tento nástroj má velmi příhodné jméno Cargo a je možné ho použít pro tři hlavní oblasti: správu projektů (překlad, spuštění testů, spuštění benchmarků), instalaci závislých knihoven (balíčků) z centrálního repositáře a publikování vlastních balíčků do centrálního repositáře. V dnešním článku se zaměříme především na první dvě zmiňované oblasti, protože s nimi se programátor začínající pracovat v Rustu pravděpodobně setká nejčastěji.

2. Základní vlastnosti a možnosti nabízené nástrojem Cargo

O některých vlastnostech nabízených nástrojem Cargo jsme se ve stručnosti zmínili již v předchozí kapitole, zkusme si ovšem jeho základní vlastnosti postupně uvést v jednotlivých bodech:

  1. Vytvoření kostry nového projektu jediným příkazem.
  2. Nový projekt může obsahovat i adresáře a soubory umožňující jeho snadnou správu a verzování s využitím SCM (současně je podporován Git a Mercurial).
  3. Automatická kontrola, které soubory je zapotřebí přeložit (tj. které soubory byly pozměněny od posledního překladu).
  4. Automatické stažení všech knihoven a jejich závislostí na základě konfigurace zapsané do souboru Cargo.toml.
  5. Spuštění projektu s možností předání parametrů příkazového řádku.
  6. Spuštění jednotkových testů, které mohou být vytvořeny společně s projektem.
  7. Spuštění benchmarků, které mohou být vytvořeny společně s projektem.
  8. Vyhledání knihovny v centrálním registru zaregistrovaných knihoven (či balíčků).
  9. Publikování vlastního balíčku v centrálním registru (crates.io)

3. Vytvoření nového projektu

Pro vytvoření nového projektu stačí použít příkaz cargo new, kterému se předá jméno projektu (to je povinné). Pokud se má vytvořit projekt, jehož výsledkem bude spustitelná aplikace, je nutné navíc použít přepínač --bin. V opačném případě by se totiž vytvořil projekt s kostrou knihovny. Vytvořme si nyní jednoduchý projekt nazvaný „project1“, po jehož překladu získáme spustitelnou aplikaci (a nikoli knihovnu):

$ <strong>cargo new --bin project1</strong>
     Created binary (application) `project1` project

Po spuštění tohoto příkazu vytvoří nástroj cargo nový adresář pojmenovaný „project1“. V tomto adresáři nalezneme mj. i soubory a adresáře určené pro správce verzí Git (toto implicitní chování je však možné změnit):

$ <strong>cd project1</strong>

$ <strong>ls -la</strong>
total 28
drwxr-xr-x  4 tester tester 4096 lis 18 22:56 .
drwxr-xr-x 10 tester tester 4096 lis 19 16:02 ..
-rw-r--r--  1 tester tester   44 lis 18 22:55 Cargo.lock
-rw-r--r--  1 tester tester  114 lis 18 22:54 Cargo.toml
drwxr-xr-x  6 tester tester 4096 lis 19 16:02 .git
-rw-r--r--  1 tester tester    7 lis 18 22:54 .gitignore
drwxr-xr-x  2 tester tester 4096 lis 18 22:54 src

Pokud vám nevyhovuje, že se automaticky vytvořily soubory a adresáře určené pro Git, lze použít volbu --vcs none:

$ <strong>cd ..</strong>

$ <strong>cargo new --bin --vcs none project2</strong>
     Created binary (application) `project2` project

Struktura tohoto projektu vypadá nepatrně odlišně (vytvoří se vlastně jen dva soubory, přičemž zdrojový soubor je uložen v podadresáři src):

$ <strong>cd project2</strong>

$ <strong>ls -la</strong>
total 16
drwxr-xr-x  3 tester tester 4096 lis 19 16:11 .
drwxr-xr-x 11 tester tester 4096 lis 19 16:12 ..
-rw-r--r--  1 tester tester  114 lis 19 16:11 Cargo.toml
drwxr-xr-x  2 tester tester 4096 lis 19 16:11 src

Taktéž je možné specifikovat, že se při inicializaci projektu má vytvořit adresářová struktura kompatibilní s Mercurialem:

$ <strong>cd ..</strong>

$ <strong>cargo new --bin --vcs hg project3</strong>
     Created binary (application) `project3` project
$ <strong>cd project3</strong>

$ <strong>ls -la</strong>
total 24
drwxr-xr-x  4 tester tester 4096 lis 19 16:18 .
drwxr-xr-x 12 tester tester 4096 lis 19 16:18 ..
-rw-r--r--  1 tester tester  114 lis 19 16:18 Cargo.toml
drwxr-xr-x  3 tester tester 4096 lis 19 16:18 .hg
-rw-r--r--  1 tester tester    7 lis 19 16:18 .hgignore
drwxr-xr-x  2 tester tester 4096 lis 19 16:18 src

Poznámka: při vytváření projektů, které budou ukládány do Gitu či Mercurialu, je nutné mít tyto nástroje nainstalované, jinak vytváření projektů skončí s chybou. Pokud například nemáte nainstalovaný Mercurial, bude vytvoření projektu neúspěšné, ovšem samotný popis chyby může být poněkud kryptický:

$ <strong>cargo new --bin --vcs hg project4</strong>
error: Failed to create project `project4` at `/home/tester/temp/project4`

To learn more, run the command again with --verbose.

$ <strong>cargo new --bin --vcs hg project4 --verbose</strong>
error: Failed to create project `project4` at `/home/tester/temp/project4`

Caused by:
  Could not execute process `hg init /home/tester/temp/project4` (never executed)

Caused by:
  No such file or directory (os error 2)

4. Struktura adresáře s projektem

Podívejme se, jak vlastně vypadá struktura adresáře, v němž je uložený celý projekt. Ihned po vytvoření projektu je struktura velmi jednoduchá a obsahuje pouze projektový soubor nazvaný Cargo.toml a kostru zdrojového kódu uloženou v souboru src/main.rs:

$ <strong>cd project1</strong>

$ <strong>tree</strong>
├── Cargo.toml
└── src
    └── main.rs

1 directory, 2 files

Ve skutečnosti jsme však tento projekt inicializovali takovým způsobem, že obsahuje i soubory a adresáře používané Gitem. Tyto soubory (.gitingore) a adresáře (.git) nejsou implicitně zobrazovány, protože začínají tečkou:

$ <strong>tree -a</strong>
.
├── Cargo.toml
├── .git
│   ├── config
│   ├── description
│   ├── HEAD
│   ├── hooks
│   │   ├── applypatch-msg.sample
│   │   ├── commit-msg.sample
│   │   ├── post-update.sample
│   │   ├── pre-applypatch.sample
│   │   ├── pre-commit.sample
│   │   ├── prepare-commit-msg.sample
│   │   ├── pre-push.sample
│   │   ├── pre-rebase.sample
│   │   └── update.sample
│   ├── info
│   │   └── exclude
│   ├── objects
│   │   ├── info
│   │   └── pack
│   └── refs
│       ├── heads
│       └── tags
├── .gitignore
└── src
    └── main.rs

10 directories, 17 files

Poznámka: v dalším textu budeme soubory používané Gitem popř. Mercurialem ignorovat, protože jejich existence či naopak neexistence nemá prakticky žádný vliv na další operace s projektem prováděné přes nástroj Cargo.

5. Projektové soubory

Z hlediska nástroje Cargo je nejdůležitější projektový soubor nazvaný jednoduše Cargo.toml. Tento soubor je vytvořen automaticky při inicializaci projektu, ovšem předpokládá se, že ho bude programátor měnit v závislosti na potřebách konkrétního projektu. Originální podoba tohoto souboru pro projekt nazvaný „project1“ vypadá následovně:

[package]
name = "project1"
version = "0.1.0"
authors = ["Pavel Tisnovsky <ptisnovs@redhat.com>"]

[dependencies]

Soubor Cargo.toml obsahuje metadata o projektu, z tohoto důvodu se mu také říká Manifest. Povšimněte si, že formát souboru vlastně odpovídá INI souborům známým z mnoha dalších aplikací (tyto soubory byly velmi často používány i ve starších verzích operačního systému Windows). Nástroj Cargo dokáže metadata zpracovat a v případě potřeby i vyexportovat do formátu JSON, a to následujícím příkazem:

$ <strong>cargo metadata</strong>

{"packages":[{"name":"project1","version":"0.1.0","id":"project1 0.1.0 (path+file:///home/tester/temp/project1)","source":null,"dependencies":[],"targets":[{"kind":["bin"],"name":"project1","src_path":"/home/tester/temp/project1/src/main.rs"}],"features":{},"manifest_path":"/home/tester/temp/project1/Cargo.toml"}],"resolve":{"root":"project1 0.1.0 (path+file:///home/tester/temp/project1)","nodes":[{"id":"project1 0.1.0 (path+file:///home/tester/temp/project1)","dependencies":[]}]},"version":1}

Výstup je určen pro zpracování dalšími nástroji, které dokážou pracovat s formátem JSON, ovšem pro lepší čitelnost lze použít on-line pretty printer:

{
    "packages":[
        {
            "name":"project1",
            "version":"0.1.0",
            "id":"project1 0.1.0 (path+file:///home/tester/temp/project1)",
            "source":null,
            "dependencies":[

            ],
            "targets":[
                {
                    "kind":[
                        "bin"
                    ],
                    "name":"project1",
                    "src_path":"/home/tester/temp/project1/src/main.rs"
                }
            ],
            "features":{

            },
            "manifest_path":"/home/tester/temp/project1/Cargo.toml"
        }
    ],
    "resolve":{
        "root":"project1 0.1.0 (path+file:///home/tester/temp/project1)",
        "nodes":[
            {
                "id":"project1 0.1.0 (path+file:///home/tester/temp/project1)",
                "dependencies":[

                ]
            }
        ]
    },
    "version":1
}

Po prvním překladu aplikace se kromě souboru Cargo.toml automaticky vytvoří i soubor Cargo.lock. Tento soubor se (většinou) neupravuje ručně, ale je spravován samotným Cargem, které si do tohoto souboru ukládá informace o knihovnách, na nichž projekt závisí apod. V našem jednoduchém projektu bude obsah souboru Cargo.lock minimalistický:

[root]
name = "project1"
version = "0.1.0"

6. Překlad projektu a spuštění výsledného binárního souboru

Překlad projektu se provede jednoduše příkazem cargo build. Pokud nejsou v projektu specifikovány žádné závislé knihovny (a to u našeho projektu nejsou), bude překlad na naprosté většině v současnosti používaných počítačů proveden prakticky okamžitě, což je ostatně patrné i z následujícího výpisu:

$ <strong>cd project1</strong>

$ <strong>cargo build</strong>
   Compiling project1 v0.1.0 (file:///home/tester/temp/project1)
    Finished debug [unoptimized + debuginfo] target(s) in 0.37 secs

V projektu se při překladu vytvoří nový adresář target s podadresářem debug. Právě do tohoto podadresáře se generují soubory při překladu a naleznete zde i výsledný spustitelný binární soubor:

$ <strong>tree</strong>
.
├── Cargo.lock
├── Cargo.toml
├── src
│   └── main.rs
└── target
    └── debug
        ├── build
        ├── deps
        ├── examples
        ├── native
        └── project1

7 directories, 4 files

Povšimněte si důležité vlastnosti – pokud nezměníte zdrojové soubory, bude další volání příkazu cargo build rychlejší, protože se vynechá fáze překladu. To se pozná jednoduše – nebude se vypisovat řádek začínající slovem „Compile“:

$ <strong>cargo build</strong>
    Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs

Nástroj Cargo tak prakticky okamžitě nabízí základní funkcionalitu, jako známý a dnes již klasický nástroj make, ovšem bez nutnosti psát soubory Makefile (ve skutečnosti nabízí make mnohem více možností, už jen díky schopnosti volat příkazy shellu, ovšem jeho základní funkce, tj. rozhodnutí, které soubory překládat, v Cargo implementovány jsou).

Spuštění výsledného nativního souboru je snadné:

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

Poznámka: ve skutečnosti můžete přímo spustit cargo run a neprovádět fázi překladu samostatně. Cargo sám zajistí, že se přeloží nová verze aplikace a teprve ta se následně spustí.

7. Spuštění jednotkových testů

Nástroj Cargo podporuje i spouštění jednotkových testů. Příkaz pro spuštění této činnosti je snadno zapamatovatelný:

$ <strong>cargo test</strong>
   Compiling project1 v0.1.0 (file:///home/tester/temp/project1)
    Finished debug [unoptimized + debuginfo] target(s) in 0.43 secs
     Running target/debug/project1-b888664ab405e319

running 0 tests

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

Vidíme, že se ve skutečnosti nespustil žádný test, a to z toho prostého důvodu, že v projektu žádné testy nemáme definovány. Vytvořme si tedy nový projekt a přidejme do něj (jen ukázkové) jednotkové testy:

$ <strong>cargo new --bin --vcs none project4</strong>

$ <strong>cd project4</strong>
$ <strong>mkdir tests</strong>

Následně vytvoříme zdrojový kód se dvěma testy:

$ <strong>cat << END > tests/test.rs</strong>
<strong>#[test]</strong>
<strong>fn ok_test() {</strong>
<strong>}</strong>

<strong>#[test]</strong>
<strong>fn failure() {</strong>
<strong>    assert!(false);</strong>
<strong>}</strong>
<strong>END</strong>

Nyní již bude spuštění testů maličkost:

$ <strong>cargo test</strong>
    Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
     Running target/debug/project4-a361c5b0e038c111

running 0 tests

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

     Running target/debug/test-3800f163e9de7132

running 2 tests
test failure ... FAILED
test ok_test ... ok

failures:

---- failure stdout ----
        thread 'failure' panicked at 'assertion failed: false', tests/test.rs:7
note: Run with `RUST_BACKTRACE=1` for a backtrace.


failures:
    failure

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured

error: test failed

Jeden z testů podle očekávání skončil v pořádku, druhý naopak skončil s chybou (viz řádek s makrem assert!).

8. Příprava binárních souborů pro distribuci

Při sestavování projektu lze specifikovat, zda se má sestavit varianta určená pro ladění či naopak varianta pro distribuci. V průběhu sestavování varianty pro distribuci se obecně mohou provádět optimalizace, které nemají pro ladění větší význam a které by naopak mohly zbytečně sestavování prodloužit. Při přípravě finální verze se postupuje takto:

$ <strong>cargo build --release</strong>
   Compiling project1 v0.1.0 (file:///home/tester/temp/presentations/rust/projects/project1)
    Finished release [optimized] target(s) in 0.37 secs

V adresáři target se nyní budou nacházet dva podadresáře. Jeden z nich obsahuje běžnou verzi projektu určenou pro ladění, druhý pak finální optimalizovanou verzi:

.
├── Cargo.lock
├── Cargo.toml
├── src
│   └── main.rs
└── target
    ├── debug
    │   ├── build
    │   ├── deps
    │   ├── examples
    │   ├── native
    │   └── project1
    └── release
        ├── build
        ├── deps
        ├── examples
        ├── native
        └── project1

12 directories, 5 files

9. Vyčištění projektu – odstranění pracovních souborů

Nejsnadnějším způsobem, jak adresář s projektem vyčistit od pracovních souborů, je spuštění příkazu:

$ <strong>cargo clean</strong>

Adresář s projektem by měl po spuštění tohoto příkazu vypadat prakticky totožně, jako po vytvoření projektu. Přibyl pouze soubor nazvaný Cargo.lock, o němž se zmíníme v dalších kapitolách:

.
├── Cargo.lock
├── Cargo.toml
└── src
    └── main.rs

1 directory, 3 files

10. Přidání knihovny používané projektem

Nyní si vyzkoušejme, jak lze projekt nakonfigurovat takovým způsobem, aby bylo možné volat funkce z externí knihovny (balíčku). Nejprve si vytvořme nový projekt:

$ <strong>cargo new --bin --vcs none project5</strong>

$ <strong>cd project4</strong>

Následně upravme soubor src/main.rs tak, aby se v něm použily funkce a metody z balíčku rand. Program je vlastně velmi jednoduchý, protože po svém spuštění vypíše dva sloupce náhodných čísel, přičemž první sloupec bude obsahovat dekadická čísla v rozsahu -128 až 127 a sloupec druhý hexadecimální čísla 0x00 až 0xff:

extern crate rand;
use rand::Rng;

fn main() {
    let mut rng = rand::thread_rng();
    for _ in 1..11 {
        println!("{:>5}  {:02x}", rng.gen::<i8>(), rng.gen::<u8>())
    }
}

Překlad a spuštění se však v tomto případě ihned nepovede, neboť příslušná knihovna prozatím nebude k dispozici:

$ <strong>cargo run</strong>
   Compiling project5 v0.1.0 (file:///home/tester/temp/project5)
error[E0425]: unresolved name `rand::thread_rng`
 --> src/main.rs:5:19
  |
5 |     let mut rng = rand::thread_rng();
  |                   ^^^^^^^^^^^^^^^^

error: aborting due to previous error

error: Could not compile `project5`.

To learn more, run the command again with --verbose.

11. Vyhledání vhodné knihovny

Nástroj Cargo obsahuje snadno použitelnou funkci pro vyhledání knihovny (balíčku) na základě zadaného slova či sousloví. Pokud například budeme chtít v našem programu použít generátor náhodných čísel (random numbers), můžeme se pokusit vyhledat balíčky, které ve svém jménu nebo popisu obsahují slovo „rand“:

$ <strong>cargo search rand</strong>

    Updating registry `https://github.com/rust-lang/crates.io-index`
rand (0.3.14)                    Random number generators and other randomness functionality. 
derive_rand (0.1.1)              `#[derive]`-like functionality for the `rand::Rand` trait. 
rand_derive (0.1.0)              Implementation of `derive(Rand)` for `custom_derive!{}`. Produces an implementation of `rand::Rand` automatically for enums and…
rand_macros (0.1.10)             `#[derive]`-like functionality for the `rand::Rand` trait. 
ndarray-rand (0.2.0)             Constructors for randomized arrays. `rand` integration for `ndarray`.
pcg_rand (0.7.0)                 An implementation of the PCG family of random number generators in pure Rust
rand-distributions (0.1.2)       Random number distributions for use with `rand`. 
rand-pop (0.1.1)                 Trait for random removal from containers.
rand-mersenne-twister (0.1.0)    Rust implementation of Mersenne Twister PRNG algorithm
xorshift (0.1.1)                 Implementation of the high performance xoroshiro128+, xorshift128+, xorshift1024*, and splitmix64 pseudo random number generato…
... and 14 crates more (use --limit N to see more)

Vidíme, že se našlo větší množství balíčků, standardně je jich však vypsáno jen deset. V nápovědě se dozvíme, jak zvýšit počet vypsaných balíčků nepovinným parametrem --limit:

$ <strong>cargo search rand --limit 10000</strong>
    Updating registry `https://github.com/rust-lang/crates.io-index`
rand (0.3.14)                      Random number generators and other randomness functionality. 
derive_rand (0.1.1)                `#[derive]`-like functionality for the `rand::Rand` trait. 
rand_derive (0.1.0)                Implementation of `derive(Rand)` for `custom_derive!{}`. Produces an implementation of `rand::Rand` automatically for enums and…
rand_macros (0.1.10)               `#[derive]`-like functionality for the `rand::Rand` trait. 
ndarray-rand (0.2.0)               Constructors for randomized arrays. `rand` integration for `ndarray`.
pcg_rand (0.7.0)                   An implementation of the PCG family of random number generators in pure Rust
rand-distributions (0.1.2)         Random number distributions for use with `rand`. 
rand-pop (0.1.1)                   Trait for random removal from containers.
rand-mersenne-twister (0.1.0)      Rust implementation of Mersenne Twister PRNG algorithm
xorshift (0.1.1)                   Implementation of the high performance xoroshiro128+, xorshift128+, xorshift1024*, and splitmix64 pseudo random number generato…
rfmt (0.1.0)                       Another Rust source code formatter. 
rdrand (0.1.5)                     An implementation of random number generator based on rdrand and rdseed instructions
ring (0.6.0-alpha)                 Safe, fast, small crypto using Rust.
cargo-tree (0.8.0)                 A Cargo subcommand that visualizes a crate's dependency graph in a tree-like format
mayda (0.2.1)                      Compression of integer arrays, favoring decompression speed.
pumpkin (1.0.1)                    A cryptographically secure prime number generator
roulette (0.1.0)                   An efficient implementation of roulette wheel selection
combid (0.5.0)                     Generate numeric identifiers
core_collections (0.3.20161028)    This is a copy of libstd::collections with all the parts that don't work in  core removed. Most importantly, it provides HashMa…
ascii_set (0.1.0)                  Fast membership of ASCII character classes.
capsicum (0.1.1)                   Simple intuitive Rust bindings for the FreeBSD capsicum framework 
cargo-ebuild (0.1.1)               Generates an ebuild for a package using the in-tree eclasses. 
tcod (0.10.0)                      The Rust bindings for the Doryen library (a.k.a. libtcod).
yyid (0.2.4)                       YYID generator (random tokens like UUIDv4) 

12. Stažení všech závislostí

Do našeho projektu budeme chtít přidat knihovnu rand vypsanou hned na začátku seznamu. Proto upravíme projektový soubor Cargo.toml následujícím způsobem (přidáme řádek se jménem a verzí knihovny):

[package]
name = "project5"
version = "0.1.0"
authors = ["Pavel Tisnovsky <ptisnovs@redhat.com>"]

[dependencies]
rand = "0.3.14"

Následně se při prvním pokusu o sestavení projektu nejprve stáhnou všechny závislé knihovny, tedy i ty, na nichž závisí funkce knihovny rand:

$ <strong>cargo build</strong>

    Updating registry `https://github.com/rust-lang/crates.io-index`
 Downloading rand v0.3.14
 Downloading libc v0.2.17
   Compiling libc v0.2.17
   Compiling rand v0.3.14
   Compiling project1 v0.1.0 (file:///home/tester/temp/project1)
    Finished debug [unoptimized + debuginfo] target(s) in 5.63 secs

Pokud budete chtít provést nový „čistý“ překlad, není nic snazšího. Povšimněte si, že se externí knihovny již pouze překládají, ale nestahují:

$ <strong>cargo clean</strong>
$ <strong>cargo build</strong>
   Compiling libc v0.2.17
   Compiling rand v0.3.14
   Compiling project5 v0.1.0 (file:///home/tester/temp/project5)
    Finished debug [unoptimized + debuginfo] target(s) in 5.53 secs

Podívejme se ještě na obsah souboru Cargo.lock. Ten byl upraven nástrojem Cargo a obsahuje následující údaje:

[root]
name = "project5"
version = "0.1.0"
dependencies = [
 "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "libc"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "rand"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
 "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
]

[metadata]
"checksum libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8"
"checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"

Co to znamená v praxi? Pokud je tento soubor součástí projektu a někdo spustí překlad na svém počítači, použije se přesně ta samá verze závislých knihoven, a to bez ohledu na to, zda se číslo verze skutečně zvýšilo či nikoli. Je tomu tak z toho důvodu, že se v tomto souboru pamatují i SHA otisky.

13. Spuštění projektu a lokální instalace projektu

Spuštění projektu, jehož činnost závisí na externích knihovnách, je stejně snadná, jako spouštění jiného projektu. Ostatně se můžete přesvědčit sami:

$ <strong>cargo run</strong>
    Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/project5`

Na standardní výstup by se měly vypsat dva sloupce náhodných čísel, první sloupec bude obsahovat celá čísla se znaménkem (rozsah -128..127), druhý sloupec pak náhodné hexadecimální hodnoty s rozsahem 0x00 až 0xff:

    2  ff
    6  cf
   24  75
 -103  51
  -80  5b
   37  96
  -73  9e
   63  1b
  -32  1a
  118  ba

Lokální instalaci lze provést následovně:

$ <strong>cargo install</strong>
   Compiling libc v0.2.17
   Compiling rand v0.3.14
   Compiling project5 v0.1.0 (file:///home/tester/temp/project5)
    Finished release [optimized] target(s) in 5.88 secs
  Installing /home/tester/.cargo/bin/project5
warning: be sure to add `/home/tester/.cargo/bin` to your PATH to be able to run the installed binaries

V adresáři /home/tester/.cargo/bin (nahraďte „tester“ za svůj login) se bude nacházet jediný spustitelný soubor:

$ <strong>ls -l ~/.cargo/bin</strong>
total 656
-rwxr-xr-x 1 tester tester 671103 lis 19 20:09 project5

Spuštění se provede buď přímým zadáním cesty nebo přidáním adresáře do proměnné $PATH:

$ <strong>export PATH=~/.cargo/bin:$PATH</strong>
$ <strong>project5</strong>
 -126  5f
   93  1e
   92  f6
  -16  b4
   41  05
  120  af
  -78  22
   87  83
  -77  71
  -41  e7

14. Repositář s demonstračními projekty

Jednoduché projekty spravované nástrojem Cargo, které jsme si popsali v předchozích kapitolách, byly uloženy do GIT repositáře dostupného na adrese https://github.com/tisnik/presentations/:

Jméno Popis projektu Cesta k projektu
project1 kostra projektu s podporou Gitu https://github.com/tisnik/presentations/tree/master/rust/projects/project1
project2 kostra projektu, který nepoužívá SCM https://github.com/tisnik/presentations/tree/master/rust/projects/project2
project3 kostra projektu s podporou Mercurialu https://github.com/tisnik/presentations/tree/master/rust/projects/project3
project4 projekt s jednotkovým testem https://github.com/tisnik/presentations/tree/master/rust/projects/project4
project5 projekt s knihovnou, na níž závisí https://github.com/tisnik/presentations/tree/master/rust/projects/project5

15. Odkazy na Internetu

  1. Cargo, Rust's Package Manager
    http://doc.crates.io/index.html
  2. Cargo Guide
    http://doc.crates.io/guide.html
  3. The Manifest Format
    http://doc.crates.io/manifest.html#the-profile-sections
  4. Seriál Programovací jazyk Rust (Root.cz)
    https://www.root.cz/serialy/programovaci-jazyk-rust/
  5. Why do Rust programs use more memory than C?
    https://www.rust-lang.org/en-US/faq.html#why-do-rust-programs-use-more-memory-than-c
  6. Why is a Rust executable large?
    https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html
  7. A lightweight logging facade for Rust
    https://crates.io/crates/log
  8. Random number generators and other randomness functionality
    https://crates.io/crates/rand
  9. Rust - home page
    https://www.rust-lang.org/en-US/
  10. Rust - Frequently Asked Questions
    https://www.rust-lang.org/en-US/faq.html
  11. The Rust Programming Language
    https://doc.rust-lang.org/book/
  12. Rust (programming language)
    https://en.wikipedia.org/wiki/Rust_%28programming_language%29
  13. Stack Overflow - Most Loved, Dreaded, and Wanted language
    https://stackoverflow.com/research/developer-survey-2016#technology-most-loved-dreaded-and-wanted
  14. Friends of Rust (Organizations running Rust in production)
    https://www.rust-lang.org/en-US/friends.html
  15. Rust programs versus C++ g++
    https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=rust&lang2=gpp
  16. Of the emerging systems languages Rust, D, Go and Nim, which is the strongest language and why?
    https://www.quora.com/Of-the-emerging-systems-languages-Rust-D-Go-and-Nim-which-is-the-strongest-language-and-why
  17. Rust by Example
    http://rustbyexample.com/
  18. Rust oficiálně ve Fedoře
    https://mojefedora.cz/rust-oficialne-ve-fedore/
  19. String Types in Rust
    http://www.suspectsemantics.com/blog/2016/03/27/string-types-in-rust/
  20. Trait (computer programming)
    https://en.wikipedia.org/wiki/Trait_%28computer_programming%29
  21. Type inference
    https://en.wikipedia.org/wiki/Type_inference
  22. Rust Compare: Pointers & References
    http://www.rust-compare.com/site/pointers.html
  23. Rust Compare: Parameters
    http://www.rust-compare.com/site/params.html
  24. Rust vs. Go
    http://vschart.com/compare/rust/vs/go-language
  25. TIOBE index (October 2016)
    http://www.tiobe.com/tiobe-index/
  26. Git (home page)
    https://git-scm.com/
  27. Mercurial (home page)
    https://www.mercurial-scm.org/
  28. Pretty printer pro JSON (online nástroj):
    https://jsonformatter.curiousconcept.com/