Skip to content

Final exports for wasm-merge? #7976

Closed

Description

@kripken

In projects that merge files, many of the exports in the intermediate files may be meant for the others they are merged with, and not for the final binary. Having a way to declare the "final/public" exports may be useful.

Some options here, from recent discussions:

  • The metadce tool can remove exports today, but it would be a separate invocation.
  • We could add a new wasm-merge flag, perhaps like wasm-merge --final-exports=WILDCARD. Specifying the list at link-time is similar to e.g. Emscripten's EXPORTED_FUNCTIONS, but it might be very long.
  • We could use custom annotations in the individual files ("X is a final/public export"), and have wasm-merge read and use those. Some questions we'd need to resolve:
    • We want to annotate exports, not functions - functions can have multiple exports, making this ambiguous otherwise. Custom annotations lacks that atm.
    • When are the annotations used and discarded? If wasm-merge does this automatically, it would prevent intermediate merges (which may be good for compile times).

cc @dschuff @tlively @bashor @biggs0125

Activity

  1. tlively commented on Oct 20, 2025

    @tlively
    Member
    • We want to annotate exports, not functions - functions can have multiple exports, making this ambiguous otherwise. Custom annotations lacks that atm.

    Annotations are allowed anywhere whitespace is allowed in the text format, so we are free to design these annotations however we wish. For example, something like this:

    ;; All exports are public
    (@binaryen.public_export)
    (func $f (export "foo1") (export "foo2") ...)
    
    ;; Only "foo1" is public
    (func $f (@binaryen.public_export) (export "foo1") (export "foo2") (...)
    
    ;; "foo2" is public.
    (@binaryen.public_export)
    (export "foo2" (func $f))

    (Similarly we can design the accompanying binary custom section however we want. There are many reasonable options there.)

    When are the annotations used and discarded? If wasm-merge does this automatically, it would prevent intermediate merges (which may be good for compile times).

    Having wasm-merge discard annotations by default but have a flag to preserve them seems simplest to me.

  2. bashor commented on Oct 27, 2025

    @bashor

    We could add a new wasm-merge flag, perhaps like wasm-merge --final-exports=WILDCARD. Specifying the list at link-time is similar to e.g. Emscripten's EXPORTED_FUNCTIONS, but it might be very long.

    It would be simpler to use a pattern for internal declarations, as we have full control over their names, unlike users' exports.

  3. bashor commented on Oct 27, 2025

    @bashor

    We want to annotate exports, not functions - functions can have multiple exports, making this ambiguous otherwise. Custom annotations lacks that atm.

    I think being able to annotate declarations (functions) would be enough in most cases.
    The main benefit of such an annotation is the ability to remove declarations themselves.
    If a declaration has both public and non-public exports, this solution will not allow you to mark and remove non-public exports during optimization; however, I believe it's solvable on the producer side.

    On the other hand, the ability to annotate exports is more flexible and simpler to use for producers.

  4. dschuff commented on Jan 7, 2026

    @dschuff
    Member

    I think this is the issue we discussed with @biggs0125 and @aheejin yesterday, right?
    Aside from these options, we also discussed name mangling as a way to designate final exports.
    Among all those options, I sort of like the idea of annotating the input file, although it would be a weak preference.
    We'd want to make sure there's a reasonable binary encoding, in addition to the text annotations. Presumably this would mean a custom section. I feel like we have recently discussed a generic way to tag functions (and other module-level entities?) with attributes for optimization, maybe this could fit into that kind of framework.

  5. aheejin commented on Jan 8, 2026

    @aheejin
    Member

    Among what I heard from the meeting, naming the internal exports in a special way (like, prefacing them with __) sounded the simplest to me. We can maybe make that a separate pass that we run after wasm-merge, namely, "RemoveExports", and make it take a string pattern with wildcards. The default can be something like __*. This way we don't need to come up with another format for annotations (both in the text format and the custom section).

  6. self-assigned this
    on May 4, 2026
  7. added a commit that references this issue on May 5, 2026
    a0981e5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions