5.1. The target specification JSON file
External resources:
- The Embedonomicon on custom targets
- rust-lang RFC on target specification JSON files
- Upstream Rust documentation on custom target specifications [outdated,
xargo
is no longer required]
Rust provides a built-in list of target specifications that are viewable via rustc --print target-list
. A custom target specification JSON file may
be written to override and tweak various target-specific options, such as linker scripts, flags, and LLVM options.
When compiling for AVR, a specific microcontroller variant/model must be targeted. This allows LLVM to generate instructions that confirm to each particular microcontroller's ABI and supported instruction set.
The target specification JSON file:
- May live in any directory - most often, committed to version control.
- Any file name you like, so long as it's JSON
- Is given to Rust via the
--target my-target-spec.json
. For example,cargo build --target ./targets/my-target-spec.json
.
An example - using the GNU toolchain for linking and compiler support libraries
Here is an example target specification JSON file for the AVR atmega328p.
This target specification:
- Enables the GNU AVR linker through the
avr-gcc
compiler frontend - Tells the linker to include
libgcc
(as compiler-rt for AVR is not yet fully supported) - Tells Rust not to pass the
--eh-frame-hdr
argument to the linker, which isn't supported by AVR-GCC and will cause and error if omitted. - Instructs LLVM to use the
avr-unknown-unknown
target specifically for theatmega328p
microcontroller - Explicitly passes an
-mmcu
argument to the linker to ensure runtime libraries are not skipped by the linker
{
"arch": "avr",
"cpu": "atmega328p",
"data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8",
"env": "",
"executables": true,
"linker": "avr-gcc",
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "avr-unknown-unknown",
"no-compiler-rt": true,
"os": "unknown",
"position-independent-executables": false,
"exe-suffix": ".elf",
"eh-frame-header": false,
"pre-link-args": {
"gcc": ["-mmcu=atmega328p"]
},
"late-link-args": {
"gcc": ["-lgcc"]
},
"target-c-int-width": "16",
"target-endian": "little",
"target-pointer-width": "16",
"vendor": "unknown"
}
Adapting to another microcontroller variant
Adapting a target specification JSON to another AVR variant is trivial.
Options that must be updated to target individual microcontroller variants:
cpu
- set to the lower-case model name of the desired AVR variantpre-link-args
- the correct-mmcu
option, always equal to thecpu
, must be updated