Compiling the C code

In order to compile a C/C++ file with Emscripten, we'll use the emcc command. We need to pass some arguments to the compiler to ensure we get a valid output that we can utilize in the browser. To generate a Wasm file from a C/C++ file, the command follows this format:

emcc <file.c> -Os -s WASM=1 -s SIDE_MODULE=1 -s BINARYEN_ASYNC_COMPILATION=0 -o <file.wasm>

Here's a breakdown of each of the arguments for the emcc command:

Argument Description
<file.c> Path of the C or C++ input file that will be compiled down to a Wasm module; we'll replace this with the actual file path when we run the command.
-Os Compiler optimization level. This optimization flag allows for module instantiation without requiring Emscripten's glue code.
-s WASM=1 Tells the compiler to compile code to WebAssembly.
-s SIDE_MODULE=1 Ensures only a WebAssembly module is output (no glue code).
-s BINARYEN_ASYNC_COMPILATION=0

From official docs:

Whether to compile the wasm asynchronously, which is more efficient and does not block the main thread. This is currently required for all but the smallest modules to run in V8.
-o <file.wasm> Path of output file .wasm file. We'll replace this with the desired output path when we run the command.

 

To test if Emscripten is working correctly, open the integrated terminal in VS Code and run the following commands:

# Ensure you're in the /chapter-04-installing-deps folder:
cd chapter-04-installing-deps

# Compile the main.c file to main.wasm:
emcc main.c -Os -s WASM=1 -s SIDE_MODULE=1 -s BINARYEN_ASYNC_COMPILATION=0 -o main.wasm

It may take a minute to compile the file the first time, but subsequent builds will be much faster. If the compilation was successful, you should see a main.wasm file in the /chapter-04-installing-deps folder. If you encounter an error, Emscripten's error message should be descriptive enough to help you correct the issue.

If everything completed successfully, you can view the Wat associated with the main.wasm file by right-clicking main.wasm in VS Code's file explorer and selecting Show WebAssembly from the context menu. The output should look like this:

(module
(type $t0 (func (param i32)))
(type $t1 (func (param i32 i32) (result i32)))
(type $t2 (func))
(type $t3 (func (result f64)))
(import "env" "table" (table $env.table 2 anyfunc))
(import "env" "memoryBase" (global $env.memoryBase i32))
(import "env" "tableBase" (global $env.tableBase i32))
(import "env" "abort" (func $env.abort (type $t0)))
(func $_addTwoNumbers (type $t1) (param $p0 i32) (param $p1 i32) (result i32)
get_local $p1
get_local $p0
i32.add)
(func $runPostSets (type $t2)
nop)
(func $__post_instantiate (type $t2)
get_global $env.memoryBase
set_global $g2
get_global $g2
i32.const 5242880
i32.add
set_global $g3)
(func $f4 (type $t3) (result f64)
i32.const 0
call $env.abort
f64.const 0x0p+0 (;=0;))
(global $g2 (mut i32) (i32.const 0))
(global $g3 (mut i32) (i32.const 0))
(global $fp$_addTwoNumbers i32 (i32.const 1))
(export "__post_instantiate" (func $__post_instantiate))
(export "_addTwoNumbers" (func $_addTwoNumbers))
(export "runPostSets" (func $runPostSets))
(export "fp$_addTwoNumbers" (global 4))
(elem (get_global $env.tableBase) $f4 $_addTwoNumbers))

If the compiler ran successfully, you're ready to move on to the next step and write JavaScript code to interact with the module, which we'll cover in the next chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset