5

I've just started to study substrate, and the Add a Pallet tutorial already has me seriously confused:

It is important to note that the Substrate runtime compiles to both a native Rust std binary and a WebAssembly (Wasm) binary. For more information about compiling std and no_std features, see XXX.

This is fine, I'm familiar with std and no_std. My impression is that you either have std enabled and compile to native Rust binary, or you don't and compile to WASM binary.

But then, when I check out the runtime's lib.rs, I find the following:

#![cfg_attr(not(feature = "std"), no_std)]
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit = "256"]

// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

// ...

This confuses me: Why is the WASM binary "made available" when std is enabled? I would have expected the opposite. And what exactly does "made available" mean in this context?

I dug a little deeper and found the following in an older version of the tutorial, which goes a little more into detail, causing even more grievous mental confusion:

This is important to enable the Substrate runtime to compile to both native binaries (which support Rust std) and Wasm binaries (which do not: no_std).

(Again, this is fine, although I'm not sure what they mean by "support".) And then later, refering to the file whose first lines I've posted above:

You can see that at the top of the file, we define that we will use no_std when we are not using the std feature. A few lines lower you can see #[cfg(feature = "std")] above the wasm_binary.rs import, which is a flag saying to only import the WASM binary when we have enabled the std feature.

What?!

So, if std is enabled, then we use the Rust std library and WASM? And when std is not enabled, then we only use libcore? This seems to completely contradict the earlier statements.

I am absolutely certain that all of this is the result of a seriously stupid mistake on my part, but I can't figure it out.

Edit. I've had an extremely enlightening conversation with Shawn Tabrizi on this topic: https://github.com/substrate-developer-hub/substrate-docs/issues/531

mkl
  • 635
  • 1
  • 6
  • 16
  • Hi @mkl, Can you please support our Substrate StackExchange proposal: https://area51.stackexchange.com/proposals/126136 – Shawn Tabrizi Dec 16 '21 at 13:15

1 Answers1

4

The Substrate runtime code (including the pallets) has two compilation target: std for the native binary and no_std for the wasm binary. This is necessary because Substrate supports to run both the wasm runtime for upgradability, and the native binary for performance (or for testing easily).

When you compile a blockchain, it will call the custom build script (build.rs in your runtime crate) to build the wasm binary first, save it in the build dir, and then build the native binary with the wasm binary embedded in wasm_binary.rs. This answered your question about "made available".

Therefore the following code means, if it's in std mode, it will include the wasm file built in no_std mode, embedded in the wasm_binary.rs file.

#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
h4x3rotab
  • 141
  • 4
  • 1
    Thank you very much. This clears some things up, but I'm not 100% clear on this. So the idea is that `build.rs` builds the Wasm binary of `lib.rs` with `std` not enabled. And if `std` is enabled, then the native binary is built with the Wasm binary embedded, correct? But what if `std` is not enabled? Then `build.rs` is _still_ executed and builds the Wasm binary, right? But isn't then a `no_std` native binary built (which doesn't have the Wasm binary embedded), as well? – mkl Nov 11 '21 at 18:41
  • 2
    As far as I can tell, it’s extremely rare to build the runtime in no_std mode directly. The no_std build is usually only initiated from build.rs. However if you have to do so, it’s likely the runtime will be still built ti the wasm target, but then it won’t be embedded to the outer build because it’s not std. – h4x3rotab Nov 14 '21 at 18:46
  • Thank you! I believe that clears everything up. – mkl Nov 15 '21 at 20:59