# Getting a ethereum-consensus build in embeded Rust > This guide was incredibly valuable while figureing this out http://blog.timhutt.co.uk/std-embedded-rust/index.html The goal was to get a version of ethereum-spec.rs to build for an embeded target with no existing standard library or OS syscalls. This must be able to deserialize SSZ encoded Ethereum containers (e.g. state, blocks), do BLS signature verification and compute state transitions. ## Issues This was a huge pain with lots of little puzzles to solve. I'll try and document them as best as I can - Adding #![no_std] to a crate only prevents the crate itself from using std. It doesn't enforce anything about the dependencies so unless every dependency (and their dependencies etc) also doesn't use std it is going to leak in somewhere so we are going to have to build it - When building for a non-whitelisted target (e.g not Wasm, windows, mac, linux) then using the std crate requires the `#![feature(restricted_std)]` crate attribute. This adds a few annoyances: - We now need to use nightly rust - This needs to be set for every crate that is still using std, not just the root crate. This is a real killer since it means we need to patch any remaing crate that uses std (not just alloc, or core) features. ## Solutions First up we are lucky that a team is alreay working on modifying the ethereum-consensus.rs crate to work for Wasm (no-std but whitelisted). This has been hugely helpful even if their work is a bit sloppy. I think if we collaborate with them and also Alex Stokes we can get a nice version of this in the main branch. I ended up forking their no-std branch and making a bunch of changes to remove unused dependences and features to really strip it down. I was able to remove a LOT of dependencies including big ones like serde. After pruning it only has 6 direct dependencies. > Cool trick you can use `cargo udeps` in combination with features to see if some dependencies should be set to optional but are not e.g. `cargo +nightly udeps --no-default-features` will tell you if any dependencies should be `optional=true`. --- I also forked `ssz-rs` and did the same thing. I was able to drop a number of dependencies and fix any issues there. Unfortunately we can now only build with nightly and I think building with all the features enabled might be broken. But we can smooth this out and merge back upstream at some point. > Another learning. If a dependency is included multiple times (for example as a build dependency and a regular one) it will bring in the union of all features. This sucks if we are trying to eliminate as many features as possible so always check the build and dev dependencies and set the features there as well. --- One sticking point was the milagro-bls crate. This replaced the blst crate from the original ethereum spec but doesn't require OS specific build things so can be built for embedded. Unfortunately they didn't think to either not use `std` or add the feature flag so I had to fork two milagro crates and patch them to add `#![feature(restricted_std)]`. After this they worked great! ## Result I was able to build the zipline-state-transition crate for a MIPS target using local (non-docker) cross-compilation. Just run install the required things and run `build.sh` from the mips state tx directory. Ideally we want to build with docker so I will get that working again soon. The resulting binary is 8.5MB which is pretty small and sweet. > Note I was able to build on the latest nightly rust so whatever regression Peppy encountered seems to have been resolved and we don't need to pin the version to one from like a year ago.