While playing with WebAssembly, I noticed that if I export a function in a file (called b.zig), and I import this file from my main file (called a.zig), then the function from b.zig is exported only if I use some other things from b.zig.
I made a minimal example here : https://codeberg.org/alberic89/tmp_4c0TFlCZf6
a.zig
const b = @import("b.zig");
export const greetings = "Hello from Zig!";
// This part is either comment or not to produce two different outputs
// comptime {
// @export(&b.favorite_number, .{ .name = "manual_favorite_number" });
// }
b.zig
pub export const favorite_number: u8 = 42;
The compilation gave me as WASM file. If the manual export is commented or not, I get this from wasm-objdump -x:
without_manual_export.wasm
without_manual_export.wasm: file format wasm 0x1
Section Details:
Memory[1]:
- memory[0] pages: initial=17
Global[2]:
- global[0] i32 mutable=1 - init i32=1048576
- global[1] i32 mutable=0 <greetings> - init i32=1048576
Export[2]:
- memory[0] -> "memory"
- global[1] -> "greetings"
Data[1]:
- segment[0] memory=0 size=20 - init i32=1048576
- 0100000: 0400 1000 4865 6c6c 6f20 6672 6f6d 205a ....Hello from Z
- 0100010: 6967 2100 ig!.```
with_manual_export.wasm
with_manual_export.wasm: file format wasm 0x1
Section Details:
Memory[1]:
- memory[0] pages: initial=17
Global[4]:
- global[0] i32 mutable=1 - init i32=1048576
- global[1] i32 mutable=0 <favorite_number> - init i32=1048576
- global[2] i32 mutable=0 <manual_favorite_number> - init i32=1048576
- global[3] i32 mutable=0 <greetings> - init i32=1048580
Export[4]:
- memory[0] -> "memory"
- global[1] -> "favorite_number"
- global[2] -> "manual_favorite_number"
- global[3] -> "greetings"
Data[1]:
- segment[0] memory=0 size=24 - init i32=1048576
- 0100000: 2a00 0000 0800 1000 4865 6c6c 6f20 6672 *.......Hello fr
- 0100010: 6f6d 205a 6967 2100 om Zig!.```
You can see that in the first case there is no value favorite_number from b.zig, while in the second case the favorite_number and manual_favorite_number are both present.
What is the rationale behind this behavior ?
My hypothesis is that b.zig is not evaluated if I do not directly use it, so the export is not taken in account.
How to prevent this from appening ?
Is there a magic trick to tell to the compiler to look in all imported files ? Or is there another idiomatic way to do it ?