Build with Cargo
Alright, lets just take a look at commit bcea609, and see how everything works.
tree
.
├── rust/ ...
├── first
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── do-rust.sh
│ ├── gba.json
│ └── src
│ ├── lang.rs
│ └── main.rs
└── gba
├── Cargo.toml
└── src
├── gfx.rs
└── lib.rs
4 directories, 9 files
We've split out our generic gba code to the gba
folder, which is it's own cargo crate. It currently just contains the gfx
module from last time, with no real modifications.
Then, we have our crate first
for our first example, which looks like a cargo crate, but with two extra aditions only, do-rust.sh
, and gba.json
.
We really still require our shell script do-rust.sh
for a few reasons. Lets take a look:
#!/bin/bash -ex
mkdir -p out
LIBS=~/.multirust/toolchains/nightly/lib/rustlib/gba.json/lib
mkdir -p $LIBS
# Call rustc to compile libcore for us.
# This is slow, maybe switch to a makefile?
[ -e $LIBS/libcore.rlib ] ||
rustc --target=gba.json -Z no-landing-pads ../rust/src/libcore/lib.rs \
--out-dir $LIBS
cargo build --target=gba.json --release
# I have no idea what it's in target/gba
arm-none-eabi-objcopy -O binary target/gba/release/first out/first.gba
gbafix out/first.gba
open out/first.gba
So, the main steps are: 1. Compiling libcore. 2. Calling cargo build
3. Doing the objcopy and gbafix.
Note I store the libcore
binaries in
LIBS=~/.multirust/toolchains/nightly/lib/rustlib/gba.json/lib
which is automatically searched by cargo. I am using multirust, and I've set the entire project to use the nightly compiler (rustc 1.6.0-nightly (9303055f3 2015-11-19)
).
There's nothing special in our first/Cargo.toml
at all, just a path dependancy on gba
[package]
name = "first"
version = "0.0.1"
authors = ["Theo Belaire"]
[dependencies]
gba = {path = "../gba"}
And the gba
crate has even less. (For now!).
So we just need to pass gba.json
, (the new name of target.json
) to cargo when building.
{
"data-layout" : "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a:0:64-n32",
"llvm-target" : "arm-none-eabi",
"ar" : "arm-none-eabi-ar",
"linker" : "arm-none-eabi-gcc",
"target-endian" : "little",
"target-pointer-width": "32",
"cpu" : "arm7tdmi",
"arch" : "arm",
"relocation-model" : "static",
"dynamic-linking" : "false",
"os" : "none",
"executables" : true,
"no-compiler-rt" : true,
"no-default-libraries": true,
"archive-format" : "gnu",
"pre-link-args" : [
"-specs=gba.specs",
"-lsysbase",
"-lc"
]
}
It's just passing the gba.specs
file from before to arm-none-eabi-gcc
. We already saw how that file looked in gba-rust-1. Turns out we didn't actually need to use clang at all, nor take it apart. Ah, we live and learn.
This is actually a pretty nice minimal example now, you can clone it, and place a copy of the rust source at rust
, and compile away, and it'll Just Work (TM).
Next time, we invoke I lied. We're playing with Input next. Then build.rs
magic to link against a C file I steal from TONC nicely, and also play around with the different modes of rendering bitmaps on the gba.build.rs
after that.