From b799c74689e77ede32c0c62eb7c4a07b00e1fba0 Mon Sep 17 00:00:00 2001 From: PerseoGI Date: Wed, 4 Jun 2025 14:55:44 +0200 Subject: [PATCH 1/3] Added emscripten documentation --- examples/cross_build.rst | 1 + examples/cross_build/emscripten.rst | 256 ++++++++++++++++++ .../emscripten/bindings-devtools.png | Bin 0 -> 159681 bytes .../emscripten/bindings-webpage.png | Bin 0 -> 68721 bytes images/integrations/conan-emscripten-logo.png | Bin 0 -> 19222 bytes integrations.rst | 1 + integrations/emscripten.rst | 14 + 7 files changed, 272 insertions(+) create mode 100644 examples/cross_build/emscripten.rst create mode 100644 images/examples/cross_build/emscripten/bindings-devtools.png create mode 100644 images/examples/cross_build/emscripten/bindings-webpage.png create mode 100644 images/integrations/conan-emscripten-logo.png create mode 100644 integrations/emscripten.rst diff --git a/examples/cross_build.rst b/examples/cross_build.rst index 7d61808020a6..a5f3e4f9ad41 100644 --- a/examples/cross_build.rst +++ b/examples/cross_build.rst @@ -9,5 +9,6 @@ Cross-building examples cross_build/toolchain_packages cross_build/android/ndk cross_build/android/android_studio + cross_build/emscripten cross_build/tricore cross_build/linux_to_windows_mingw diff --git a/examples/cross_build/emscripten.rst b/examples/cross_build/emscripten.rst new file mode 100644 index 000000000000..f56d2ec1bc2f --- /dev/null +++ b/examples/cross_build/emscripten.rst @@ -0,0 +1,256 @@ +.. _examples_cross_build_emscripten: + +Cross-building with Emscripten +============================== + +This example demonstrates how to cross-build a simple C++ project using Emscripten and Conan. + +Conan supports building for both `asm.js `_ and `WASM +`_, giving you the flexibility to target different +JavaScript/WebAssembly runtimes in the browser. + +We recommend creating separate Conan profiles for each target. Below are +recommended profiles and instructions on how to build with them. + +What’s the difference between asm.js and WASM? +---------------------------------------------- + +- **asm.js** is a subset of JavaScript optimized for speed. It is fully supported by all browsers (even older ones) and compiles to a large ``.js`` file. +- **WebAssembly (WASM)** is a binary format that is smaller and faster to load and execute. Most modern browsers support it, and it is generally recommended for new projects. ``WASM`` is also easier to integrate with native browser APIs compared to ``asm.js``. + +Setting Up Conan Profiles +------------------------- + +**For asm.js (JavaScript-based output):** + +.. code-block:: text + + include(default) + [settings] + arch=asm.js + build_type=Release + os=Emscripten + + [tool_requires] + emsdk/[*] + + [conf] + tools.build:exelinkflags=['-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=2GB', '-sINITIAL_MEMORY=64MB'] + tools.build:sharedlinkflags=['-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=2GB', '-sINITIAL_MEMORY=64MB'] + +**For WebAssembly (WASM):** + +.. code-block:: text + + include(default) + [settings] + arch=wasm + build_type=Release + os=Emscripten + + [tool_requires] + emsdk/[*] + + [conf] + tools.build:exelinkflags=['-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB'] + tools.build:sharedlinkflags=['-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB'] + +.. note:: + + ``wasm`` arch refers to ``WASM 32-bit`` target architecture, which is the + default. If you wish to target ``WASM64``, set ``arch=wasm64`` in your profile. + **Note that WASM64 is still experimental** and requires Node.js v20+ and a browser that supports it. + +.. note:: + + The profiles above use the ``emsdk`` package from Conan Center, which provides the Emscripten SDK, including ``emcc``, ``em++``, and tools like ``emrun`` and ``node``. + + If you prefer to use your system-installed Emscripten instead of the Conan-provided one, remove the `tool_requires` section from the profiles and instead set: + + .. code-block:: text + + tools.build:compiler_executables={'c':'/path/to/emcc', 'cpp':'/path/to/em++'} + +Example Usage +------------- + +Please, first clone the sources to recreate this project. You can find them in the +`examples2 repository `_ in GitHub: + +.. code-block:: bash + + $ git clone https://github.com/conan-io/examples2.git + $ cd examples2/examples/cross_build/emscripten/bindings + + +You can check the contents of the project: + +.. code-block:: text + + . + ├── CMakeLists.txt + ├── conanfile.py + ├── main.cpp + ├── shell.html + └── ... + + +As we can see in the conanfile and CMakeLists.txt, this project depends on an external library, `eigen `_. +This library is used to perform a simple floating point operation and to +demonstrate how easy it is to cross-build a project with emscripten using Conan even if it depends on external libraries. + +To simplify the CMakeLists.txt, all the ``Emscripten`` specific configuration +have been moved to the conanfile.py, only one line is needed in the +CMakeLists.txt to enable the generation of the ``html`` output (testing +purposes). + +The main.cpp file contains some basic functions which will be called from +JavaScript. Notice the usage of ``EMSCRIPTEN_KEEPALIVE`` specifier to ensure that +the functions are not removed by the Emscripten optimizer, allowing them to be +called from JavaScript. This could be avoided by using the ``-s EXPORTED_FUNCTIONS`` flag. + +In the conanfile.py we may focus on the ``generate()`` method, more specifically in the following lines: + +.. code-block:: python + + def generate(self): + ... + tc.extra_exelinkflags.append( + "-sEXPORTED_FUNCTIONS=['_malloc','_free'] \ + -sEXPORTED_RUNTIME_METHODS=['ccall','cwrap','getValue','setValue','HEAPF32'] \ + -sENVIRONMENT=web \ + -sALLOW_MEMORY_GROWTH=1 \ + -sNO_EXIT_RUNTIME=1 \ + --shell-file ${CMAKE_SOURCE_DIR}/shell.html" + ) + +This line is crucial as it specifies the ``Emscripten`` flags that will be used +during the linking phase. It exports the necessary functions to be callable +from JavaScript, sets the environment to web, allows memory growth, and +prevents the runtime from exiting immediately after execution. +Also, defines the ``shell.html`` file. This file will act as a ``html`` template to produce the final output. + + +These linker options could also be passed from CMakeLists.txt using the +``set_target_properties()`` command. + +And finally, the ``shell.html`` file is a slightly modified version of the default shell packaged in ``emsdk`` with the following changes: + +- Simplified to only include the necessary scripts and styles. +- Added buttons and input fields to act as a user interface for the exported functions. +- Added in the ``