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 :
cargo-component through CLI args (I looked and didn't find anything relevant to this) ? In a fork of cargo-component ? In a fork of wit-component ? Or in a fork of wasmparser ? Thanks in advance for the help !
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 proposalor 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.
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
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.
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
Could you file an issues win Wasmtime with steps for reproduction ? That looks like a bug
I did it's issue #11300
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 ?
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.
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.
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 !
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 ?
I suspect the easiest way would be to either disable validation in cargo-component or updating cargo-component to enable all features during validation
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