Stream: cargo-component

Topic: Generating component using the `custom-page-size` proposal


view this post on Zulip Antoine Lavandier (Jul 22 2025 at 10:17):

I hope that this is the proper place to ask for help.
It's all in the title. I am trying to compile components while using the custom-page-size proposal.

Here's what I've done:
Copy the example from https://component-model.bytecodealliance.org/language-support/rust.html and verified that cargo-component build --release works.

Compile LLVM's LLD 21.0-git from source to have a version of wasm-ld that supports the custom-page-size proposal. It's available since this PR.
Put the following in my .cargo/config.toml

[build]
rustflags = [
    "-Clinker=wasm-ld", # Override linker
    "-Clink-arg=--page-size=1", # Enable Custom page size
    "-Clink-arg=--initial-memory=16000", # 16K of Memory
    "-Clink-arg=-zstack-size=1024", # Default stack-size is 1MB, bring it down to 1KiB
]

tried to run cargo-component build --release
Got the following error message

error: failed to decode world from module

Caused by:
    0: module was not valid
    1: the custom page sizes proposal must be enabled to customize a memory's page size (at offset 0x79)

My questions are :

Thanks in advance for the help !

This commit adds support for WebAssembly's custom-page-sizes proposal to wasm-ld. An overview of the proposal can be found here. In a sentence, it allows customizing a Wasm memory's page si...

view this post on Zulip Antoine Lavandier (Jul 22 2025 at 11:57):

After reading this again, my first question does not make sense because some words are missing.

Is trying to generate such components useful or it is pointless because the correct way to use components in conjunctions should to use/import them in modules that themselves use this proposal or is it pointless because components are supposed to be integrated in WebAssembly modules that themselves can use custom page sizes ?

Answering my own question, If I read the Component Model Documentation properly, Components can include modules, not the other way around, so the component needs to use custom-page-size proposal. This leaves the problem of how to actually turn a module with a page size of 1 into a component with a page size of 1.

view this post on Zulip Antoine Lavandier (Jul 22 2025 at 13:38):

Update:
After cloning wasmparser, commenting the appropriate lines to basically always enable custom page sizes in wasmparser, cloning other repositories to force them to use my local wasmparser and finally installing my local cargo-component I was able to get all the build to building the .cwasm file.

However, Component::deserialize_raw() fails with

failed to deserialize pre-compiled module: failed to parse precompiled artifact as an ELF

Caused by:
    Invalid ELF header size or alignment
CLI and Rust libraries for low-level manipulation of WebAssembly modules - bytecodealliance/wasm-tools

view this post on Zulip Alex Crichton (Jul 22 2025 at 14:16):

Is trying to generate such components useful

IMO, yes! Work on custom-page-sizes is ongoing so not everything is working just yet, but passing extra linker flags is indeed the vision for how it's supposed to work.

where do I tell the parser that I want to enable the proposal?

I think this is something for the cargo-component codebase itself. My recommendation for there would be to enable all the features all the time because that way you don't have to worry about adding flags and such.

view this post on Zulip Alex Crichton (Jul 22 2025 at 14:16):

failed to deserialize pre-compiled module: failed to parse precompiled artifact as an ELF

Could you file an issue win Wasmtime with steps for reproduction? That looks like a bug

view this post on Zulip Antoine Lavandier (Jul 22 2025 at 15:23):

Could you file an issues win Wasmtime with steps for reproduction ? That looks like a bug

I did it's issue #11300

Test Case Wasm Component bytecode Wasm Component source code All the relevant code I used is in this repo Steps to Reproduce (Optional) Build the component from source using cargo-component build. ...

view this post on Zulip Antoine Lavandier (Jul 23 2025 at 09:34):

I tried again using the commit from the PR that fixes my issue (0e6d9c679) and I'm happy to report that I managed to deserialize a component that was built with custom-page-size enabled. Now I'm having an unrelated issue which is that running Store::new leads to an allocation of exactly 512KiB (524288 Bytes) and since I'm trying to run this on hardware that has less than that in RAM it's a problem. I hope that reducing the memory that my Component ask for would help but it doesn't seem to. I also set config.memory_reservation(65536) both when pre-compiling and when deserializing the component.

I'm surprised by that 512 KiB number since in this other Zulip Conversation when trying to use precompiled-modules they didn't seem to run into this allocation.
This makes me think that this is specific to components. Do you have any where this allocation could come from and if it can be reduced ?

view this post on Zulip Antoine Lavandier (Jul 23 2025 at 12:28):

Turns out using config.max_wasm_stack() was the way to go. 512KiB is the default value and I guess it actually reserves this maximum size for each store.

view this post on Zulip Alex Crichton (Jul 23 2025 at 14:30):

Yeah there are a number of knobs for low-memory usage you'll need to turn, and max_wasm_stack is definitely one of them.

view this post on Zulip Antoine Lavandier (Jul 23 2025 at 14:52):

After tinkering with some other configuration settings, I was able to get a complete program running a component, that included the *.cwasm ELF, wasmtime with the features component-model, runtime and pulley and the OS I'm using to run on my hardware (an NRF52840dk) to weigh about 350k with some further compile time optimizations so I'm happy. Thanks for the help !

view this post on Zulip Antoine Lavandier (Jul 23 2025 at 15:45):

Looking back on this, the only thing I don't have a good solution to is the first one, that is how to have a custom-page-sizes enabled cargo-component. I ended up making it depend on a local clone of wasmparser that has this proposal enabled by default by commenting out some lines. I don't think that there is any other way to achieve this at this time. I tried to change it in cargo-component itself but didn't manage to how to. Do you happen to know if it's possible or it needs to be done first by downstream crates like wit-bindgen ?

view this post on Zulip Alex Crichton (Jul 23 2025 at 16:17):

I suspect the easiest way would be to either disable validation in cargo-component or updating cargo-component to enable all features during validation

view this post on Zulip Alex Crichton (Jul 23 2025 at 16:17):

so still on the cargo-component side of things, but I don't know precisely where that would be


Last updated: Dec 06 2025 at 06:05 UTC