From d4eb4d2c47c905b3634410a7fdfea84fe1e8cee0 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 8 May 2019 14:08:09 +0200 Subject: [PATCH] write generated code to disk for easier inspection 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` --- book/en/src/by-example/tips.md | 64 ++++++++++++++++++++++++++++++++++ macros/src/lib.rs | 11 +++++- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/book/en/src/by-example/tips.md b/book/en/src/by-example/tips.md index 79b9d71e0f..4936bd279f 100644 --- a/book/en/src/by-example/tips.md +++ b/book/en/src/by-example/tips.md @@ -113,3 +113,67 @@ Here's an example where `heapless::Pool` is used to "box" buffers of 128 bytes. ``` console $ cargo run --example binds {{#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 +``` diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 441d6b5ee9..736289cb4b 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -4,6 +4,8 @@ extern crate proc_macro; use proc_macro::TokenStream; +use std::{fs, path::Path}; + use syn::parse_macro_input; mod analyze; @@ -304,5 +306,12 @@ pub fn app(args: TokenStream, input: TokenStream) -> TokenStream { let analysis = analyze::app(&app); // 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() }