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
4. Struktura adresáře s projektem
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
13. Spuštění projektu a lokální instalace projektu
14. Repositář s demonstračními projekty
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:
- Vytvoření kostry nového projektu jediným příkazem.
- 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).
- Automatická kontrola, které soubory je zapotřebí přeložit (tj. které soubory byly pozměněny od posledního překladu).
- Automatické stažení všech knihoven a jejich závislostí na základě konfigurace zapsané do souboru Cargo.toml.
- Spuštění projektu s možností předání parametrů příkazového řádku.
- Spuštění jednotkových testů, které mohou být vytvořeny společně s projektem.
- Spuštění benchmarků, které mohou být vytvořeny společně s projektem.
- Vyhledání knihovny v centrálním registru zaregistrovaných knihoven (či balíčků).
- 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
- Cargo, Rust's Package Manager
http://doc.crates.io/index.html - Cargo Guide
http://doc.crates.io/guide.html - The Manifest Format
http://doc.crates.io/manifest.html#the-profile-sections - Seriál Programovací jazyk Rust (Root.cz)
https://www.root.cz/serialy/programovaci-jazyk-rust/ - 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 - Why is a Rust executable large?
https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html - A lightweight logging facade for Rust
https://crates.io/crates/log - Random number generators and other randomness functionality
https://crates.io/crates/rand - Rust - home page
https://www.rust-lang.org/en-US/ - Rust - Frequently Asked Questions
https://www.rust-lang.org/en-US/faq.html - The Rust Programming Language
https://doc.rust-lang.org/book/ - Rust (programming language)
https://en.wikipedia.org/wiki/Rust_%28programming_language%29 - Stack Overflow - Most Loved, Dreaded, and Wanted language
https://stackoverflow.com/research/developer-survey-2016#technology-most-loved-dreaded-and-wanted - Friends of Rust (Organizations running Rust in production)
https://www.rust-lang.org/en-US/friends.html - Rust programs versus C++ g++
https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=rust&lang2=gpp - 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 - Rust by Example
http://rustbyexample.com/ - Rust oficiálně ve Fedoře
https://mojefedora.cz/rust-oficialne-ve-fedore/ - String Types in Rust
http://www.suspectsemantics.com/blog/2016/03/27/string-types-in-rust/ - Trait (computer programming)
https://en.wikipedia.org/wiki/Trait_%28computer_programming%29 - Type inference
https://en.wikipedia.org/wiki/Type_inference - Rust Compare: Pointers & References
http://www.rust-compare.com/site/pointers.html - Rust Compare: Parameters
http://www.rust-compare.com/site/params.html - Rust vs. Go
http://vschart.com/compare/rust/vs/go-language - TIOBE index (October 2016)
http://www.tiobe.com/tiobe-index/ - Git (home page)
https://git-scm.com/ - Mercurial (home page)
https://www.mercurial-scm.org/ - Pretty printer pro JSON (online nástroj):
https://jsonformatter.curiousconcept.com/
4. 5. 2017 at 23:01
TOML neni (jen) INI. Ve skutecnosti je to docela pekny konfiguracni „jazyk“, prave tim, ze v zakladu pripomina ini, ale ve skutecnosti se silou vyrovna jsoun nebo yamlu. Na rozdil od jsonu se lepe edituje, na rozdil od yamlu nema 2d syntaxi, ale hlavne ma specifikaci a knihovny pro ruzne jazyky.
https://github.com/toml-lang/toml
Osobne bych ho doporucil jako konfiguracni jazyk pro nove projekty.