-
Notifications
You must be signed in to change notification settings - Fork 27
Guides
This page will guide you through common steps to get the most out of our toolchain.
Unit tests are a fundamental tool to develop any software, especially when the complexity grows. Even though the Nintendo 3DS doesn't have official support for the test crate, ctru-rs implements a custom test runner, from which we can take some hints.
To run the ctru-rs unit tests directly on the the console, you should build them via this command:
cargo 3ds test --package ctru-rs --lib
This runs the tests directly on the console using 3dslink (you can specify --no-run to just build the testing 3dsx file). Because std tests are sadly not working in the current state of our toolchain, we will specify --package ctru-rs to only build this library's unit tests. Finally, we use --lib to avoid building and running all examples, since 3dslink can't send off multiple binaries.
The testing framework is incredibly raw, but that's to be expected, since the official Rust tools are made to be run on the host system and not in cross-compilation.
Thanks to Luma3DS, the most modern CFW around, we can debug programs in real time with gdb. To do so you will need to install gdb on your host computer and acquire the rust-gdb script (it comes with your Rust installation).
On your console, follow these steps:
- Open the Homebrew Launcher on your modded 3DS
- Open the Rosalina Menu (the button combo to do this is usually
L + Down + Select) - Select "Debugger options"
- Press "Enable debugger"
- Press "Force-debug next application at launch"
- Remember the remote port and IP address it tells you to use!
Now, on your computer:
- Run your application in
debugmode (you can do this remotely usingcargo 3ds run) - Once you run the program, the console should start waiting in a black screen.
- Locate the built
.elffile (you can find it in thetargetfolder, usually attarget/armv6k-nintendo-3ds/debug/<app-name>.elf)
With the file at hand, you can run this simple command:
rust-gdb <file-path>
With this you should find yourself in the normal gdb CLI. If you want to connect to your 3DS, simply do
(gdb) target remote <ip-address>:<port>
And you're in! You can now use breakpoints, read memory, step or continue through the program as in normal gdb. Thanks to rust-gdb, you'll even have pretty notation for Rust types.
Sometimes, however, you’ll need to have support for the custom OS ABI, which is only available in the arm-none-eabi-gdb included with devkitARM. You can run that instead of rust-gdb if you find yourself in tricky situations.
Happy debugging!
rust-analyzer is a language server for Rust, with tons of useful features like autocomplete, documentation hovers, and more. If you're not already using it, check out the "Quick Start" on their homepage to install and set it up.
Even though it normally works great with the default configuration, the rust3ds toolchain has some extra requirements to make it work with projects built for the 3DS. For the best experience, you'll need to set some configuration. Here are some examples for common code editors:
{
"lsp": {
"rust-analyzer": {
"initialization_options": {
"cargo": {
"target": "armv6k-nintendo-3ds"
},
"check": {
"overrideCommand": [
"cargo",
"3ds",
// or "clippy" if you want to use clippy
"check",
"--message-format=json"
]
}
}
}
}
}
{ // Use cargo-3ds to drive "check on save". This avoids cache thrashing when alternating // between rust-analyzer and running cargo-3ds from the command line "rust-analyzer.check.overrideCommand": [ "cargo", "3ds", // or "clippy" if you want to use clippy "check", "--message-format=json-diagnostic-rendered-ansi", ], // even with overrideCommand, this is still needed for build scripts to work properly: "rust-analyzer.cargo.target": "armv6k-nintendo-3ds", "rust-analyzer.server.extraEnv": { // Adjust as needed to point to your installation of devkitPro: "DEVKITPRO": "/opt/devkitpro", "DEVKITARM": "/opt/devkitpro/devkitARM", // This should be the same as your usual $PATH, but with devkitPro paths added to the beginning. // Might not be necessary if you already added these to your host $PATH. "PATH": "/opt/devkitpro/devkitARM/bin:/opt/devkitpro/tools/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin", }, }