knurling-rs / defmt

Efficient, deferred formatting for logging on embedded systems
https://defmt.ferrous-systems.com/
Apache License 2.0
750 stars 69 forks source link

defmt-test build fails for non-CortexM thumb targets #829

Open matthewjrichey opened 2 months ago

matthewjrichey commented 2 months ago

Our team is using defmt-test as a foundation for several unit and integration tests. Our target processor is a Cortex R core, and we build for the following architecture targets:

armv8r-none-eabihf thumbv8r-none-eabihf

Most of our development occurred while building and testing with armv8r-...; we have only recently started using thumbv8r-.... When we made the switch to thumb, our test builds started failing with the following error:

   Compiling cortex-m v0.7.7
error: failed to run custom build command for `cortex-m v0.7.7`

Caused by:
  process didn't exit successfully: `/workdir/build/debug/build/cortex-m-73e6882762cfa3ea/build-script-build` (exit status: 101)
  --- stderr
  thread 'main' panicked at /opt/cargo/registry/src/index.crates.io-6f17d22bba15001f/cortex-m-0.7.7/build.rs:25:10:
  called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

At first we wondered why the cortex-m crate was even being built for a non-CortexM target architecture (armv8r), but then we looked at the defmt-test dependencies in Cargo.toml:

[dependencies]
cortex-m-rt = "0.7"
cortex-m-semihosting = "0.5"
...

Looking further into the issue, we found that switching from arm to thumb target invokes this code in the build of the cortex-m crate:

    if target.starts_with("thumb") {
        ...
        fs::copy(
            format!("bin/{}{}.a", target, suffix),
            out_dir.join(format!("lib{}.a", name)),
        )
        .unwrap();
        ...
    }

This unwrap() is panicking because it is looking for a .a file that does not exist, because the crate is being built for an incompatible target architecture. With armv8r (i.e. target.starts_with("thumb") is false), this part of the build script is never invoked and the build succeeds.

Overall, we are wondering if you would consider removing this hard dependency on the cortex M crates from defmt-test. Perhaps you could put this behind a default feature flag that could be turned off when using armv8r or similar target architectures. We have had great success using defmt-test so far. That is, our test binaries build and execute successfully with the main() provided by defmt-test, when built for armv8r. We would like to continue using and building more tests upon the defmt-test foundation. However, we also would like to build for thumbv8r, and without forking the defmt repo there is currently no way we can think of to do this. In our minds there should be a way for us to "opt out" of the Cortex M requirement here.

Thank you for your consideration.

Urhengulas commented 2 months ago

Hi @matthewjrichey, we are happy to hear to enjoy working with defmt-test! 😁

Support for Cortex-R sounds like a great idea and beneficial to the community. If you want to make the changes, I'd be happy to review and merge them.

Otherwise you can contract us to implement the change. If you are interested just shoot us a message at https://ferrous-systems.com/contact/.

matthewjrichey commented 2 months ago

Thanks for your reply!

I will consult with my team and see what we want to do. Stay tuned.