emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.67k stars 3.29k forks source link

No list of possible EXPORTED_RUNTIME_METHODS available in documentation. #22162

Open sike-0 opened 3 months ago

sike-0 commented 3 months ago

I have gone over the emscripten documentation several times by now and the documentation always seems incomplete. Let's take an example code I used recently.

main.c

#include <stdio.h>
#include <emscripten.h>

EMSCRIPTEN_KEEPALIVE
void sayName(char* string) {
    printf("%s\n", string);
}

Now, I want to pass a string from Javascript side to the function sayName

I used the following command to compile main.c because I'm using it in a svelte app. emcc main.cpp -o test.js -sMODULARIZE -s EXPORT_ES6=1 -s ALLOW_MEMORY_GROWTH=1 -s EXPORT_ALL=1 -lembind --emit-tsd test.d.ts

I used the following code in the App.svelte file

<script lang="ts">
  import Module from "./test.js";
  import type { MainModule } from "./test";
  let m: MainModule;
  Module().then((module) => {
    m = module;
    console.log(m);
    const name = "svelte app";
    const namePtr = m.stringToNewUTF8(name);
    m._sayName(namePtr);
  });
</script>

According to what's described in the documentation, this should work.

But instead, I get this error

TypeError: m.stringToNewUTF8 is not a function

I look up the error and find out the correct solution in this issue because the entire emscripten documentation doesn't mention that stringToNewUTF8 is supposed to be passed as a command line parameter -sEXPORTED_RUNTIME_METHODS="stringToNewUTF8"

image

Since I was printing the Module object (m in my case) in the js code, I found that all exported functions appear in that object. So to test it out, I try exporting another function, readPointer with the command line parameter: sEXPORTED_RUNTIME_METHODS="['stringToNewUTF8','readPointer']" And I get warning: invalid item in EXPORTED_RUNTIME_METHODS: readPointer

How do I know which item is valid?

sbc100 commented 3 months ago

readPointer is part of the embind library so it only available when you build with -lembind. In your test did you build with this flag?:

$ emcc test/hello_world.c -sEXPORTED_RUNTIME_METHODS=readPointer 
warning: invalid item in EXPORTED_RUNTIME_METHODS: readPointer
emcc: warning: warnings in JS library compilation [-Wjs-compiler]
$ emcc test/hello_world.c -sEXPORTED_RUNTIME_METHODS=readPointer -lembind

Note that the warning went away with the second command line that includes -lembind.

The list of symbols that you can use with -sEXPORTED_RUNTIME_METHODS is any/all of the JS library symbols, which are present in the JS library files that you specify on the command line (or in the default library files) that are here: https://github.com/emscripten-core/emscripten/tree/main/src. I'm not sure it would be practical to enumerate all them in the documentation... but perhaps would could do it? Maybe just a list of all of them somewhere?

sike-0 commented 3 months ago

Note that the warning went away with the second command line that includes -lembind.

I works when I don't use the --emit-tsd test.d.ts flag

I'm not sure it would be practical to enumerate all them in the documentation... but perhaps would could do it? Maybe just a list of all of them somewhere?

It would be really helpful to have a list of them in documentation, otherwise people won't be able to utilize all the features emscripten provides.

mmontag commented 2 months ago

+1. This is a pain point. Can we get a summary of all possible EXPORTED_FUNCTIONS and EXPORTED_RUNTIME_METHODS?

In fact, the longer this list would be, the more it is needed.

sbc100 commented 2 months ago

I guess I would be OK with such as list, but only if its auto-generated, other it would be perpetually out-of-date.