I'm curious if it's possible to have emscripten build a binary without libc.
If I have simple.c:
int add1(int x) {
return x + 1;
}
And I don't want to include any of libc, is that possible?
My best attempt so far has been:
emcc simple.c -s NO_FILESYSTEM=1 -s DISABLE_EXCEPTION_CATCHING=1 -s DEFAULT_LIBRARY_FUNCS_TO_INCLUDE='[]' -s LIBRARY_DEPS_TO_AUTOEXPORT='[]' -s EXPORTED_FUNCTIONS='["add1"]' -s USE_SDL=0 -o simple.js -nostdlib
But the generated output still includes symbols for malloc, string conversion routines, and so on.
I'm also interested in the same process for generating webassembly; that is, my real goal is generating a webassembly module that contains only a single function. Is this possible with emscripten?
Emscripten compiles to WebAssembly by default, but you can also compile to JS for older browsers.
The Emscripten Compiler Frontend ( emcc ) is used to call the Emscripten compiler from the command line. It is effectively a drop-in replacement for a standard compiler like gcc or clang.
Binaryen is a compiler and toolchain infrastructure library for WebAssembly, written in C++. It aims to make compiling to WebAssembly easy, fast, and effective: Easy: Binaryen has a simple C API in a single header, and can also be used from JavaScript.
Emscripten is not currently well-suited for this use case. Object files are bitcode, and anytime linking is used, it wants to include some libraries and JS module code.
For WebAssembly, it is possible to use clang from upstream LLVM trunk along with the s2wasm
tool from Binaryen. Clang (optionally in conjunction with LLVM's llc
tool) can generate a .s
assembly file which s2wasm
can convert into wast
(WebAssembly's text format). This file can be converted to wasm binary using Binaryen's wasm-as
tool or the wast2wasm
tool from WABT. This pipeline will turn any undefined references to functions from the C file into wasm imports, which you'll need to manually hook up to JavaScript functions.
There are a few examples of this floating around on the Internet (I found some by googling "webassembly clang s2wasm"). Note also that s2wasm
does the linker's job of laying out the wasm linear memory, and it has several options that you'll want to be aware of; see its help output and its sources, e.g. the tool and linker code.
You can use the option -s ONLY_MY_CODE=1
to get a file containing only your compiled code.
See the possible options you can pass to emscripten.
You have 2 options to build standalone wasm module. Via emsdk
or via llvm
. Note, that now emsdk generates code via asm.js backend, and does not support natively some i64 operations like multiplication.
emcc your_module.c -v -O3 -s WASM=1 -s SIDE_MODULE=1 -o your_module.wasm
Note, now you need latest llvm from trunk, compiled with wasm support.
clang -emit-llvm --target=wasm32 -O3 -c -o your_module.bc your_module.c
llc -asm-verbose=false -o your_module.s your_module.bc
s2wasm --emscripten-glue your_module.s > your_module.wast
wasm-opt -O3 your_module.wast -o your_module.wasm
See WebAssembly Standalone, there is also a link to examples in this page.
emcc simple.c -Os -s WASM=1 -s SIDE_MODULE=1 -o simple.wasm
To run it in html/js you must provide an imports
object with imports.env={memoryBase, tableBase, memory, table}
. But if you convert wasm file by wabt to wat format you can strip the import section because you don't need neither memory nor table then compile it back to wasm.
Here is an exemple
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With