-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Configure C function exports correctly for emscripten targets #39171
Comments
We've already got lists of symbols that we explicitly pass to the linker to export, so this shouldn't be too hard to implement as well! |
I'd like to try to implement this in a PR. |
Kinda implemented this locally but there are two issues/caveats:
[
"_foo",
"_main",
"___udivmodti4",
"___fixsfti",
"___fixunsdfti",
"___floattisf",
"___muloti4",
"___modti3",
"___divti3",
"___umodti3",
"___udivti3",
"___fixdfti",
"___floatuntisf",
"___multi3",
"___floattidf",
"___fixunssfti",
"___floatuntidf",
"___lshrti3",
"___ashrti3",
"___ashlti3",
"___rust_reallocate",
"___rust_reallocate_inplace",
"___rust_deallocate",
"___rust_allocate",
"___rust_usable_size",
"___rust_start_panic",
"_rust_eh_personality",
"___rust_maybe_catch_panic"
] As you can see, apart from own exported
Should we somehow filter those or even allow only top-level exports? |
main isn't fully required, you can add #![no_main] to your crate-level
attributes, which lets you compile it.
2017-01-22 20:26 GMT+01:00 Ingvar Stepanyan <notifications@github.com>:
… Kinda implemented this locally but there are two issues/caveats:
1.
Apparently JS is generated only for binary target, so to export
functions you still need to compile with such target and have at least
empty main function.
2.
To achieve this, I've patched export_symbols function in linker which
seems like a proper place; however, it seems like symbols are collected
from all dependent crates too, so the list of exported functions looks like:
[
"_foo",
"_main",
"___udivmodti4",
"___fixsfti",
"___fixunsdfti",
"___floattisf",
"___muloti4",
"___modti3",
"___divti3",
"___umodti3",
"___udivti3",
"___fixdfti",
"___floatuntisf",
"___multi3",
"___floattidf",
"___fixunssfti",
"___floatuntidf",
"___lshrti3",
"___ashrti3",
"___ashlti3",
"___rust_reallocate",
"___rust_reallocate_inplace",
"___rust_deallocate",
"___rust_allocate",
"___rust_usable_size",
"___rust_start_panic",
"_rust_eh_personality",
"___rust_maybe_catch_panic"
]
As you can see, apart from own exported _main (required) and _foo
(explicitly exported), tons of others are added, and some of them are
incompatible with Emscripten which makes it complain:
LLVM ERROR: Function __ashlti3 has illegal integer argument
Traceback (most recent call last):
File "/Users/rreverser/cf-repos/rust/emsdk_portable/emscripten/incoming/emcc", line 13, in <module>
emcc.run()
File "/Users/rreverser/cf-repos/rust/emsdk_portable/emscripten/incoming/emcc.py", line 1647, in run
final = shared.Building.emscripten(final, append_ext=False, extra_args=extra_args)
File "/Users/rreverser/cf-repos/rust/emsdk_portable/emscripten/incoming/tools/shared.py", line 1745, in emscripten
call_emscripten(cmdline)
File "/Users/rreverser/cf-repos/rust/emsdk_portable/emscripten/incoming/emscripten.py", line 1836, in _main
temp_files.run_and_clean(lambda: main(
File "/Users/rreverser/cf-repos/rust/emsdk_portable/emscripten/incoming/tools/tempfiles.py", line 78, in run_and_clean
return func()
File "/Users/rreverser/cf-repos/rust/emsdk_portable/emscripten/incoming/emscripten.py", line 1841, in <lambda>
DEBUG=DEBUG,
File "/Users/rreverser/cf-repos/rust/emsdk_portable/emscripten/incoming/emscripten.py", line 1742, in main
temp_files=temp_files, DEBUG=DEBUG)
File "/Users/rreverser/cf-repos/rust/emsdk_portable/emscripten/incoming/emscripten.py", line 91, in emscript
funcs, metadata, mem_init = get_and_parse_backend(infile, settings, temp_files, DEBUG)
File "/Users/rreverser/cf-repos/rust/emsdk_portable/emscripten/incoming/emscripten.py", line 160, in get_and_parse_backend
backend_output = open(temp_js).read()
Should we somehow filter those or even allow only top-level exports?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#39171 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABYmbt6lV-8QqpT8Pd6lRBfA9Bu4FXpiks5rU61ngaJpZM4LnoOa>
.
|
@CryZe I guess; anyway, that wasn't my main point, just wanted to clarify "for rustc to do this automatically for cdylib and staticlib targets" from the first comment. |
@RReverser some of those are existing bugs in the compiler (such as |
@alexcrichton Apparently they're coming from libcompiler_builtins which does export them explicitly:
|
@RReverser indeed! I'm working on a patch (alexcrichton@9048de6) to fix this but it'll take a moment to finish testing. |
@alexcrichton No problem, just let me know when I should send a PR. In the meanwhile, instead of condition in GnuLinker's export_symbols, I defined a separate Linker for Emscripten with support for passing optimization levels, debug levels, and now playing to see whether I can add dynamic linking support. |
@RReverser I've posted a PR for that change. |
I wonder if this is the correct behavior. Perhaps asmjs staticlibs and/or cdylibs should be .js? |
I honestly don't know what extensions we emit for all the output types for asmjs. |
It looks to me like asm.js uses the default extension types for dylibs and staticlibs, .so, and .a. I'd say that staticlibs being .a is correct for something you are going to run through emcc, but maybe .so should be .js. Are we really emitting .so files? |
@brson We are not - we simply prohibit dynamically linked libs altogether AFAIK. I think what we really should do is generate them via Emscripten's SIDE_MODULE / MAIN_MODULE mechanism, but that requires a little bit more investigation. Btw, I've left my laptop with changes at the office, will rebase & submit PR for this issue on Monday if that works for you. Would be nice to finally get some first PR into Rust :) |
Sounds good @RReverser ! |
It claims to accept most GNU linker options, but in fact most of them have no effect and instead it requires some special options which are easier to handle in a separate trait. Currently added: - `export_symbols`: works on executables as special Emscripten case since staticlibs/dylibs aren't compiled to JS, while exports are required to be accessible from JS. Fixes rust-lang#39171. - `optimize` - translates Rust's optimization level to Emscripten optimization level (whether passed via `-C opt-level=...` or `-O...`). Fixes rust-lang#36899. - `debuginfo` - translates debug info; Emscripten has 5 debug levels while Rust has 3, so chose to translate `-C debuginfo=1` to `-g3` (preserves whitespace, variable and function names for easy debugging). Fixes rust-lang#36901. - `no_default_libraries` - tells Emscripten to exlude `memcpy` and co.
Add Emscripten-specific linker Emscripten claims to accept most GNU linker options, but in fact most of `-Wl,...` are useless for it and instead it requires some additional special options which are easier to handle in a separate trait. Currently added: - `export_symbols`: works on executables as special Emscripten case since staticlibs/dylibs aren't compiled to JS, while exports are required to be accessible from JS. Fixes rust-lang#39171. - `optimize` - translates Rust's optimization level to Emscripten optimization level (whether passed via `-C opt-level=...` or `-O...`). Fixes rust-lang#36899. - `debuginfo` - translates debug info; Emscripten has 5 debug levels while Rust has 3, so chose to translate `-C debuginfo=1` to `-g3` (preserves whitespace, variable and function names for easy debugging). Fixes rust-lang#36901. - `no_default_libraries` - tells Emscripten to exclude `memcpy` and co. TODO (in future PR): dynamic linking via `SIDE_MODULE` / `MAIN_MODULE` mechanism.
Add Emscripten-specific linker Emscripten claims to accept most GNU linker options, but in fact most of `-Wl,...` are useless for it and instead it requires some additional special options which are easier to handle in a separate trait. Currently added: - `export_symbols`: works on executables as special Emscripten case since staticlibs/dylibs aren't compiled to JS, while exports are required to be accessible from JS. Fixes rust-lang#39171. - `optimize` - translates Rust's optimization level to Emscripten optimization level (whether passed via `-C opt-level=...` or `-O...`). Fixes rust-lang#36899. - `debuginfo` - translates debug info; Emscripten has 5 debug levels while Rust has 3, so chose to translate `-C debuginfo=1` to `-g3` (preserves whitespace, variable and function names for easy debugging). Fixes rust-lang#36901. - `no_default_libraries` - tells Emscripten to exclude `memcpy` and co. TODO (in future PR): dynamic linking via `SIDE_MODULE` / `MAIN_MODULE` mechanism.
It claims to accept most GNU linker options, but in fact most of them have no effect and instead it requires some special options which are easier to handle in a separate trait. Currently added: - `export_symbols`: works on executables as special Emscripten case since staticlibs/dylibs aren't compiled to JS, while exports are required to be accessible from JS. Fixes rust-lang#39171. - `optimize` - translates Rust's optimization level to Emscripten optimization level (whether passed via `-C opt-level=...` or `-O...`). Fixes rust-lang#36899. - `debuginfo` - translates debug info; Emscripten has 5 debug levels while Rust has 3, so chose to translate `-C debuginfo=1` to `-g3` (preserves whitespace, variable and function names for easy debugging). Fixes rust-lang#36901. - `no_default_libraries` - tells Emscripten to exlude `memcpy` and co.
Add Emscripten-specific linker Emscripten claims to accept most GNU linker options, but in fact most of `-Wl,...` are useless for it and instead it requires some additional special options which are easier to handle in a separate trait. Currently added: - `export_symbols`: works on executables as special Emscripten case since staticlibs/dylibs aren't compiled to JS, while exports are required to be accessible from JS. Fixes #39171. - `optimize` - translates Rust's optimization level to Emscripten optimization level (whether passed via `-C opt-level=...` or `-O...`). Fixes #36899. - `debuginfo` - translates debug info; Emscripten has 5 debug levels while Rust has 3, so chose to translate `-C debuginfo=1` to `-g3` (preserves whitespace, variable and function names for easy debugging). Fixes #36901. - `no_default_libraries` - tells Emscripten to exclude `memcpy` and co. TODO (in future PR): dynamic linking via `SIDE_MODULE` / `MAIN_MODULE` mechanism.
In order to call emscriptened functions from JS one must pass
-s EXPORTED_FUNCTIONS=[...]
to emcc, with each exported symbol. ISTM that it would be consistent for rustc to do this automatically for cdylib and staticlib targets.cc @CryZe @alexcrichton
The text was updated successfully, but these errors were encountered: