flowchart LR A(Python) --> B[fname.py file] B --> C[python fname.py] C --> D{hello world} E(Rust) --> F[fname.rs file] F --> G[rustc fname.rs] G --> H[./fname] H --> I{hello world}
Build
Systems in Rust
Announcements
- The second homework, “Hi cargo”, is ready after this class.
- It is comically trivial.
- Mostly makes sure you have everything set up.
- Due Friday, 12 Sept. at 1440 ET.
Today
- Hybrid Day
- Build system/package manager
- Theory behind Cargo
- Trap in Cargo
- Use Cargo
Build Systems
Interpretation
- We once again address interpretation vs. compilation
- I think of this as programming vs. scripting
- We can think in terms of languages - Rust/C vs. Python/JavaScript
Scripts
- I regard a script a:
- Text file
- Which describes actions for a computer
- Readable to humans
- And readable to a program (like
python
) which can direct the computer to act
- We note that this is much closer to being a text file that it is to being a program.
Programs
- We can create programs but we also use existing programs.
- As an example, consider the Firefox web-browser
- If you use Chrome, keep that to yourself, that’s embarassing.
- This is what “Firefox.exe” looks like on a Window device.
Firefox.exe
A{Ÿ@€ÿw.·þ9ÏCñ~¿‰ó€Ë @€ÿ¶ûCþD8ßué¬% Aƒù/„î% L‹RHƒÂHƒÀM…Ò…wÿÿÿM…À„à ID$¹ÿ A·ƒú-…“ IPMHfAƒx-IDÑD·fE…À„| E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùc…P D·BfE…À„A E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùo… D·BfE…À„ E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùn…Ú D·BfE…À„Ë E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùt…Ÿ D·BfE…À„ E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùe…d D·B
fE…À„U E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùn…) D·BfE…À„ E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùt…î D·BfE…À„ß E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùp…³ D·BfE…À„¤ E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùru|D·BfE…ÀtqE·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùouID·BfE…Àt>E·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùcufƒz „* ë ƒú/„i# L‹ HƒÀM…À…GýÿÿHŒ$ð è)˜ fïÀL„$ fA@ fA@fA H„$à H‰D$ HÇÁÿÿÿÿ1ÒA¹0 èE …Àˆ# L‹„$H ¹ 1Òÿû H‰ÃH…À„;# L´$@ AÇFà AÆFø LŒ$à AÇ H‰Ùº M‰ðÿõú L‰ÿ…À„4# €¼$8 …_# D‹„$ L¼$0 L‰ùL‰òè™ A€ …X# L´$ AÇFà AÆFø 1ÉL‰òA¸ ÿ0ù = t…À…! ÿù ·èÍ €…ÀNèA¼) @¶L=t˜ H‰ØHÿÀHƒør H‰Ùÿ°÷ @„ö…*" A€÷³1íH
¤ ÿ’ü H…ÀL‹d$`…6# L‹M…À„w ID$¹ÿ A·ƒú-tƒú/„»! L‹ HƒÀM…ÀuâéJ IPMHfAƒx-IDÑD·fE…ÀtÓE·ÈA9ÉDCÁEH¿E‰ÂA€Ê A€ùE¶ÊECÈA€ùlu«D·BfE…Àt E·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€øa…jÿÿÿD·BfE…À„[ÿÿÿE·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€øu…%ÿÿÿD·BfE…À„ÿÿÿE·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€øn…àþÿÿD·BfE…À„ÑþÿÿE·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€øc…›þÿÿD·B
fE…À„ŒþÿÿE·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€øh…VþÿÿD·BfE…À„GþÿÿE·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€øe…þÿÿD·BfE…À„þÿÿE·ÈAºÿ Aùÿ EBÐEB¿E‰ÑA€É A€øE¶ÁECÂA€ør…Ìýÿÿfƒz …ÁýÿÿH‹H‰HøHƒÀH…ÉuðAÿͰL‹d$`ë1À„Û„Æ AÇE1ÉAöÇtyL‹M…ÀtqID$¹ÿ A·ƒú-uIIPMPfAƒx-IDÒD·fE…Àt6E·ÐA9ÊDCÁEP¿E‰ÃA€Ë A€úE¶ÓECÐA€úfuéj ƒú/„$ L‹ HƒÀM…Àu™Aö×E¶ÇAƒàHŒ$ð Hœ$ H‰Úè˜ @Šs@„ö…à# ƒ¼$ I‰ÿu1íë/H
} ÿ$ù H…À…à% H
- I would not regard that as readable to humans (depends on the human)
Compilation
- Compilation is the process that takes text-based code to whatever we saw on the last slide.
- Can be quite simple - we made
hi_world
, a program, already.- Notably it didn’t do a lot.
rustc
takes a.rs
file and makes an executable- a program, sort of
- Executables run as command with
./
prefix- This differs from
python3
which runs a script without creating a corresponding program.
- This differs from
.py vs .rs
- You only have to compile once to have the executable forever.
- Most programs are executables, not scripts.
Rustc
rustc
is rarely, if ever, used directly- Over the years (since like, 1960) code has increased in complexity.
- Many files (think pgl.py, WordleGraphics.py, EnigmaRotor.py)
- Many libraries (think NumPy, pandas, scikit)
- Complex file systems (01/rustup.md)
- Over the years (since like, 1960) code has increased in complexity.
- The solution was automation.
Build Systems
- We don’t have a real equivalence to compilation for Python.
- There is Numba
- We do have a build system equivalent.
- I use flit, which is easy.
- I think there’s others… Setuptools? Hatchling?
Flit
- Flit solves a novel problem for Python programers.
- Not: Let’s make some code that I can run.
- Instead: Let’s make code that can be used in code other people run.
Packaging
- NumPy, pandas, and things like CS 151 PGL can be “built” into packages with Flit and friends.
- Basically, instead of running e.g.
python3 mycode.py
- Run
flit init
to make a new folder, edit some code, then runflit publish
to add it topip
- Basically, instead of running e.g.
- Takeaway - package management and build systems work real well together.
Wheels
- The thing that
flit
and friends create and distribute is not a.py
file. - Rather, they are “wheels” which are not human readable.
- A lot like compiled code
- Takeaway - a good way to think of Rust is that we’re writing packages for ourselves.
Cargo
- With Python, we use
python3
(orpip
, but perhaps aspython3 -m pip
). rustc
is not really the equivalent to that:- Rather, we use
cargo
, the Rust build and package manager. cargo
will handle any usage ofrustc
that we may need.- We can easily then distribute code across multiple files.
Cargo New
Build+Package
- Cargo is Rust’s build system (like
flit
) and package manager (likepip
). - We will use Cargo instead of
rustc
for the rest of the term.- My sense is that this is the industry standard.
- We’ll step through an example, then you’ll do a (very simple) exercise.
New
- The first thing to do with Cargo, as a rule, is great a new package.
- This is kinda like creating a new
.py
file. - It is a bit more like creating a Python project from a template repository.
- This is kinda like creating a new
Do it
- To do so:
cargo
is, well, Cargonew
creates a new package.throwaway_example
is the name of the package1.
Examine
- The most natural thing is to see what has changed.
- For me, I see a new directory:
throwaway_example
- I change into the directory to examine it.
- Not much there:
Aside: Tree
- Can also see directory structure.
- Install
tree
with your preferred installer (perhapsapt
orbrew
)
- Then use
tree
instead ofls
main.rs
- Cargo creates projects with a default main file.
- The name “main” is basically mainful to Cargo - it says which, if multiple,
.rs
files to read first when trying to execute the code in a package.- Make sure you understand that sentence.
Cargo Run
Run
cargo run
is probably our closest equivalent topython3 throwaway_example.py
or the “Run” button in VS Code.- Of note, you can simply do “new” then “run”.
- “New” creates a new folder.
- “Run” must be done from within that folder.
Try it
- Do this:
- See this:
Again!
- If you run again, the process will:
- Skip the compile step.
- Be way faster (∞x reported here)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
Running `target/debug/throwaway_example`
Hello, world!
- 0.56s -> 0.00s
It’s fast
- 0.56s -> 0.00s
- This is why we use languages which compile.
- Python took around .04s, for me.
- The results are:
- Guess how long it takes to compile
python
, by the way.
Other files
- Go ahead and add another
.rs
file and see what happens.- Add it to the
src
directory!
- Add it to the
- I’ll use this one - I change filename and text, but
Run it again…
- Nothing changes.
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
Running `target/debug/throwaway_example`
Hello, world!
- This is the same as adding another
.py
file then not usingimport
or including its code in any other way.
Swap the names.
- I use
mv
(move) to change:main.rs
toold_main.rs
secondary.rs
tomain.rs
- Things change!
Compiling throwaway_example v0.1.0 (/home/user/throwaway_example)
error[E0601]: `main` function not found in crate `throwaway_example`
--> src/main.rs:3:2
|
3 | }
| ^ consider adding a `main` function to `src/main.rs`
For more information about this error, try `rustc --explain E0601`.
error: could not compile `throwaway_example` (bin "throwaway_example") due to 1 previous error
Requirements
- You need a
main.rs
with a function namedmain
. nvim src/main.rs
-> Change “secondary” to “main” -> “cargo run”
Fin
Footnotes
Well, kinda. We’ll get to that.↩︎