189: write generated code to disk for easier inspection r=japaric a=japaric

now that the generated code is actually readable let's make it easier to access

this commit also documents how to inspect the generated code via
`rtfm-expansion.rs` and `cargo-expand`

Co-authored-by: Jorge Aparicio <jorge@japaric.io>
This commit is contained in:
bors[bot] 2019-05-09 19:53:56 +00:00
commit 6acb156482
2 changed files with 74 additions and 1 deletions

View file

@ -113,3 +113,67 @@ Here's an example where `heapless::Pool` is used to "box" buffers of 128 bytes.
``` console ``` console
$ cargo run --example binds $ cargo run --example binds
{{#include ../../../../ci/expected/pool.run}}``` {{#include ../../../../ci/expected/pool.run}}```
## Inspecting the expanded code
`#[rtfm::app]` is a procedural macro that produces support code. If for some
reason you need to inspect the code generated by this macro you have two
options:
You can inspect the file `rtfm-expansion.rs` inside the `target` directory. This
file contains the expansion of the `#[rtfm::app]` item (not your whole program!)
of the *last built* (via `cargo build` or `cargo check`) RTFM application. The
expanded code is not pretty printed by default so you'll want to run `rustfmt`
over it before you read it.
``` console
$ cargo build --example foo
$ rustfmt target/rtfm-expansion.rs
$ tail -n30 target/rtfm-expansion.rs
```
``` rust
#[doc = r" Implementation details"]
const APP: () = {
use lm3s6965 as _;
#[no_mangle]
unsafe fn main() -> ! {
rtfm::export::interrupt::disable();
let mut core = rtfm::export::Peripherals::steal();
let late = init(
init::Locals::new(),
init::Context::new(rtfm::Peripherals {
CBP: core.CBP,
CPUID: core.CPUID,
DCB: core.DCB,
DWT: core.DWT,
FPB: core.FPB,
FPU: core.FPU,
ITM: core.ITM,
MPU: core.MPU,
SCB: &mut core.SCB,
SYST: core.SYST,
TPIU: core.TPIU,
}),
);
core.SCB.scr.modify(|r| r | 1 << 1);
rtfm::export::interrupt::enable();
loop {
rtfm::export::wfi()
}
}
};
```
Or, you can use the [`cargo-expand`] subcommand. This subcommand will expand
*all* the macros, including the `#[rtfm::app]` attribute, and modules in your
crate and print the output to the console.
[`cargo-expand`]: https://crates.io/crates/cargo-expand
``` console
$ # produces the same output as before
$ cargo expand --example smallest | tail -n30
```

View file

@ -4,6 +4,8 @@
extern crate proc_macro; extern crate proc_macro;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use std::{fs, path::Path};
use syn::parse_macro_input; use syn::parse_macro_input;
mod analyze; mod analyze;
@ -304,5 +306,12 @@ pub fn app(args: TokenStream, input: TokenStream) -> TokenStream {
let analysis = analyze::app(&app); let analysis = analyze::app(&app);
// Code generation // Code generation
codegen::app(&input.ident, &app, &analysis).into() let ts = codegen::app(&input.ident, &app, &analysis);
// Try to write the expanded code to disk
if Path::new("target").exists() {
fs::write("target/rtfm-expansion.rs", ts.to_string()).ok();
}
ts.into()
} }