{"id":1747,"date":"2022-03-28T00:04:38","date_gmt":"2022-03-27T22:04:38","guid":{"rendered":"https:\/\/nguenkam.com\/blog\/?p=1747"},"modified":"2022-03-28T00:04:38","modified_gmt":"2022-03-27T22:04:38","slug":"emscripten-intro","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2022\/03\/28\/emscripten-intro\/","title":{"rendered":"Emscripten : intro"},"content":{"rendered":"\n<p>Emscripten is a complete&nbsp;<a href=\"https:\/\/emscripten.org\/docs\/introducing_emscripten\/emscripten_license.html#emscripten-license\">Open Source<\/a>&nbsp;compiler toolchain to WebAssembly. Using Emscripten you can:<\/p>\n\n\n\n<ul><li>Compile C and C++ code, or any other language that uses LLVM, into WebAssembly, and run it on the Web, Node.js, or other wasm runtimes.<\/li><\/ul>\n\n\n\n<p>Practically any\u00a0<strong>portable<\/strong>\u00a0C or C++ codebase can be compiled into WebAssembly using Emscripten, ranging from high-performance games that need to render graphics, play sounds, and load and process files, through to application frameworks like Qt.<\/p>\n\n\n\n<p>Emscripten generates small and fast code! Its default output format is\u00a0<a href=\"http:\/\/webassembly.org\/\">WebAssembly<\/a>\u00a0, a highly optimizable executable format, that runs almost as fast as native code, while being portable and safe. Emscripten does a lot of optimization work for you automatically, by careful integration with LLVM,\u00a0<a href=\"https:\/\/github.com\/WebAssembly\/binaryen\">Binaryen<\/a>,\u00a0<a href=\"https:\/\/developers.google.com\/closure\/compiler\">Closure Compiler<\/a>, and other tools.<\/p>\n\n\n\n<h4>Porting code to use Emscripten<\/h4>\n\n\n\n<p>Emscripten support for\u00a0<strong>portable<\/strong>\u00a0C\/C++ code is fairly comprehensive. <\/p>\n\n\n\n<p> There are differences between the native and\u00a0<a href=\"https:\/\/emscripten.org\/docs\/porting\/emscripten-runtime-environment.html#emscripten-runtime-environment\">Emscripten Runtime Environment<\/a>, which mean some changes usually need to be made to the native code. That said, many applications will only need to change the way they define their main loop, and also modify their\u00a0<a href=\"https:\/\/emscripten.org\/docs\/porting\/files\/file_systems_overview.html#file-system-overview\">file handling<\/a>\u00a0to adapt to the limitations of the browser\/JavaScript.<\/p>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">Getting started<\/span><\/h4>\n\n\n\n<ul><li>Make sure you have\u00a0<a href=\"https:\/\/emscripten.org\/docs\/getting_started\/downloads.html#sdk-download-and-install\">downloaded and installed<\/a>\u00a0Emscripten (the exact approach for doing this will depend your operating system: Linux, Windows, or Mac).<\/li><li>Emscripten is accessed using the\u00a0<a href=\"https:\/\/emscripten.org\/docs\/tools_reference\/emcc.html#emccdoc\">Emscripten Compiler Frontend (emcc)<\/a>. The Emscripten Compiler Frontend (<code>emcc<\/code>) is used to call the Emscripten compiler from the command line. It is effectively a drop-in replacement for a standard compiler like\u00a0<em>gcc<\/em>\u00a0or\u00a0<em>clang<\/em>. This script invokes all the other tools needed to build your code. \u00a0It is called on the command line using\u00a0<code>.\/emcc<\/code>\u00a0or\u00a0<code>.\/em++<\/code><\/li><\/ul>\n\n\n\n<p><em><strong>PS: <\/strong><span class=\"has-inline-color has-luminous-vivid-orange-color\">On Windows the tool is called using the slightly different syntax:\u00a0<code>emcc<\/code>\u00a0or\u00a0<code>em++<\/code>. The remainder of this tutorial uses the Linux approach (<code>.\/emcc<\/code>).<\/span><\/em><\/p>\n\n\n\n<p>For the next section you will need to open a command prompt:<\/p>\n\n\n\n<ul><li>On Linux or macOS, open a&nbsp;<em>Terminal<\/em>.<\/li><li>On Windows open the&nbsp;<a href=\"https:\/\/emscripten.org\/docs\/tools_reference\/emcmdprompt.html#emcmdprompt\">Emscripten Command Prompt<\/a>, a command prompt that has been pre-configured with the correct system paths and settings to point to the&nbsp;<a href=\"https:\/\/emscripten.org\/docs\/site\/glossary.html#term-active-tool-sdk\">active<\/a>&nbsp;Emscripten tools. To access this prompt, type&nbsp;<strong>Emscripten<\/strong>&nbsp;in the Windows 8 start screen, and then select the&nbsp;<strong>Emscripten Command Prompt<\/strong>&nbsp;option.<\/li><\/ul>\n\n\n\n<p>Navigate with the command prompt to the emscripten directory under the SDK. This is a folder below the\u00a0<a href=\"https:\/\/emscripten.org\/docs\/site\/glossary.html#term-emsdk-root-directory\">emsdk root directory<\/a>, typically\u00a0<strong>&lt;emsdk root directory>\/upstream\/emscripten\/<\/strong>. The examples below will depend on finding files relative to that location.<\/p>\n\n\n\n<h4>Verifying Emscripten<\/h4>\n\n\n\n<p>If you haven\u2019t run Emscripten before, run it now with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/emcc -v<\/code><\/pre>\n\n\n\n<p>If the output contains warnings about missing tools, see\u00a0<a href=\"https:\/\/emscripten.org\/docs\/building_from_source\/verify_emscripten_environment.html#verifying-the-emscripten-environment\">Verifying the Emscripten Development Environment<\/a>\u00a0for debugging help.<\/p>\n\n\n\n<h4>Running Emscripten<\/h4>\n\n\n\n<p>You can now compile your first C\/C++ file to JavaScript.<\/p>\n\n\n\n<p>First, lets have a look at the file to be compiled:\u00a0<strong>hello_world.c<\/strong>. This is the simplest test code in the SDK, and as you can see, all it does is print \u201chello, world!\u201d to the console and then exit.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/*\r\n * Copyright 2011 The Emscripten Authors.  All rights reserved.\r\n * Emscripten is available under two separate licenses, the MIT license and the\r\n * University of Illinois\/NCSA Open Source License.  Both these licenses can be\r\n * found in the LICENSE file.\r\n *\/\r\n\r\n#include &lt;stdio.h>\r\n\r\nint main() {\r\n  printf(\"hello, world!\\n\");\r\n  return 0;\r\n}\r\n<\/code><\/pre>\n\n\n\n<p>To build the JavaScript version of this code, simply specify the C\/C++ file after\u00a0<em>emcc<\/em>\u00a0(use\u00a0<em>em++<\/em>\u00a0to force compilation as C++):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/emcc tests\/hello_world.c<\/code><\/pre>\n\n\n\n<p>You should see two files generated by that command:\u00a0<strong>a.out.js<\/strong>\u00a0and\u00a0<strong>a.out.wasm<\/strong>. The second is a WebAssembly file containing the compiled code, and the first is a JavaScript file containing the runtime support to load and execute it. You can run them using\u00a0<a href=\"https:\/\/emscripten.org\/docs\/site\/glossary.html#term-node-js\">node.js<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>node a.out.js<\/code><\/pre>\n\n\n\n<p>This prints \u201chello, world!\u201d to the console, as expected.<\/p>\n\n\n\n<p><strong><em><span class=\"has-inline-color has-vivid-red-color\">PS: <\/span><\/em><\/strong><em>Older node.js versions do not have WebAssembly support yet. In that case you will see an error message suggesting that you build with\u00a0<code>-s\u00a0WASM=0<\/code>\u00a0to disable WebAssembly, and then emscripten will emit the compiled code as JavaScript. In general, WebAssembly is recommended as it has widespread browser support and is more efficient both to execute and to download (and therefore emscripten emits it by default), but sometimes you may need your code to run in an environment where it is not yet present and so should disable it.<\/em><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><em><strong><span class=\"has-inline-color has-vivid-green-cyan-color\">PS:<\/span><\/strong> If an error occurs when calling\u00a0emcc, run it with the\u00a0<code>-v<\/code>\u00a0option to print out a lot of useful debug informati<\/em>on.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h4>Generating HTML<\/h4>\n\n\n\n<p>Emscripten can also generate HTML for testing embedded JavaScript. To generate HTML, use the\u00a0<code>-o<\/code>\u00a0(<a href=\"https:\/\/emscripten.org\/docs\/tools_reference\/emcc.html#emcc-o-target\">output<\/a>) command and specify an html file as the target file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/emcc tests\/hello_world.c -o hello.html<\/code><\/pre>\n\n\n\n<p>You can now open\u00a0<code>hello.html<\/code>\u00a0in a web browser.<\/p>\n\n\n\n<p><em><strong><span class=\"has-inline-color has-luminous-vivid-orange-color\">PS:<\/span><\/strong> Unfortunately several browsers (including\u00a0Chrome,\u00a0Safari, and\u00a0Internet Explorer) do not support\u00a0<code>file:\/\/<\/code>\u00a0<a href=\"https:\/\/emscripten.org\/docs\/site\/glossary.html#term-xhr\">XHR<\/a>\u00a0requests, and can\u2019t load extra files needed by the HTML (like a\u00a0<code>.wasm<\/code>\u00a0file, or packaged file data as mentioned lower down). For these browsers you\u2019ll need to serve the files using a\u00a0<a href=\"https:\/\/emscripten.org\/docs\/getting_started\/FAQ.html#faq-local-webserver\">local webserver<\/a>\u00a0and then open\u00a0<code>http:\/\/localhost:8000\/hello.html<\/code>).<\/em><\/p>\n\n\n\n<h4>Using files<\/h4>\n\n\n\n<p>Your C\/C++ code can access files using the normal libc stdio API (<code>fopen<\/code>,\u00a0<code>fclose<\/code>, etc.).<\/p>\n\n\n\n<p>But JavaScript is usually run in the sandboxed environment of a web browser, without direct access to the local file system. Emscripten simulates a file system that you can access from your compiled C\/C++ code using the normal libc stdio API.<\/p>\n\n\n\n<p>Files that you want to access should be\u00a0<a href=\"https:\/\/emscripten.org\/docs\/tools_reference\/emcc.html#emcc-preload-file\">preloaded<\/a>\u00a0or\u00a0<a href=\"https:\/\/emscripten.org\/docs\/tools_reference\/emcc.html#emcc-embed-file\">embedded<\/a>\u00a0into the virtual file system. Preloading (or embedding) generates a virtual file system that corresponds to the file system structure at\u00a0<em>compile<\/em>\u00a0time,\u00a0<em>relative to the current directory<\/em>.<\/p>\n\n\n\n<p>The\u00a0<a href=\"https:\/\/github.com\/emscripten-core\/emscripten\/blob\/main\/tests\/hello_world_file.cpp\">hello_world_file.cpp<\/a>\u00a0example shows how to load a file (both the test code and the file to be loaded shown below):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Copyright 2012 The Emscripten Authors.  All rights reserved.\r\n\/\/ Emscripten is available under two separate licenses, the MIT license and the\r\n\/\/ University of Illinois\/NCSA Open Source License.  Both these licenses can be\r\n\/\/ found in the LICENSE file.\r\n\r\n#include &lt;stdio.h>\r\n\r\nint main() {\r\n  FILE *file = fopen(\"tests\/hello_world_file.txt\", \"rb\");\r\n  if (!file) {\r\n    printf(\"cannot open file\\n\");\r\n    return 1;\r\n  }\r\n  while (!feof(file)) {\r\n    char c = fgetc(file);\r\n    if (c != EOF) {\r\n      putchar(c);\r\n    }\r\n  }\r\n  fclose (file);\r\n  return 0;\r\n}<\/code><\/pre>\n\n\n\n<p>The example expects to be able to load a file located at\u00a0<strong>tests\/hello_world_file.txt<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FILE *file = fopen(\"tests\/hello_world_file.txt\", \"rb\");<\/code><\/pre>\n\n\n\n<p>We compile the example from the directory \u201cabove\u201d\u00a0<strong>tests<\/strong>\u00a0to ensure that virtual filesystem is created with the correct structure relative to the compile-time directory.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/emcc tests\/hello_world_file.cpp -o hello.html --preload-file tests\/hello_world_file.txt<\/code><\/pre>\n\n\n\n<p>The above command is used to specify a data file to\u00a0<a href=\"https:\/\/emscripten.org\/docs\/tools_reference\/emcc.html#emcc-preload-file\">preload<\/a>\u00a0into Emscripten\u2019s virtual file system \u2014 before running any compiled code. This approach is useful because Browsers can only load data from the network asynchronously (except in Web Workers) while a lot of native code uses synchronous file system access. Preloading ensures that the asynchronous download of data files is complete (and the file is available) before compiled code has the opportunity to access the Emscripten file system.<\/p>\n\n\n\n<p>\u00a0You can now open\u00a0<strong>hello.html<\/strong>\u00a0in a web browser to see the data from\u00a0<strong>hello_world_file.txt<\/strong>\u00a0being displayed.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h5>Reference<\/h5>\n\n\n\n<p><a href=\"https:\/\/emscripten.org\/docs\/index.html\">https:\/\/emscripten.org\/docs\/index.html<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Emscripten is a complete&nbsp;Open Source&nbsp;compiler toolchain to WebAssembly. Using Emscripten you can: Compile C and C++ code, or any other language that uses LLVM, into WebAssembly, and run it on the Web, Node.js, or other wasm runtimes. Practically any\u00a0portable\u00a0C or C++ codebase can be compiled into WebAssembly using Emscripten, ranging from high-performance games that need [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1772,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[516,515,513,514,422,517],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1747"}],"collection":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=1747"}],"version-history":[{"count":2,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1747\/revisions"}],"predecessor-version":[{"id":1773,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1747\/revisions\/1773"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media\/1772"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=1747"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=1747"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=1747"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}