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..d67a2c3e7ce0 --- /dev/null +++ b/examples/cross_build/emscripten.rst @@ -0,0 +1,139 @@ +.. _examples_cross_build_emscripten: + +Cross-building with Emscripten - WebAssembly and asm.js +======================================================= + +This example demonstrates how to cross-build a simple C++ project using Emscripten and Conan. + +Conan supports `WASM `_ cross compilation, 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. + + +Setting up Conan profile for WebAssembly (WASM) +----------------------------------------------- + +.. code-block:: text + + [settings] + arch=wasm + build_type=Release + compiler=emcc + compiler.cppstd=17 + compiler.libcxx=libc++ + # Optional settings to enable multithreading (see note below) + # compiler.threads=posix + compiler.version=4.0.10 + os=Emscripten + + [tool_requires] + emsdk/4.0.10 + + [conf] + # Optional settings to enable memory allocation + 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:: + + Conan also supports building for `asm.js `_ targets, which is a nowadays considered deprecated. + + 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**. + + +Even though Emscripten is not a true runtime environment (like Linux or +Windows), it is part of a toolchain ecosystem that compiles C/C++ to +WebAssembly (WASM) and asm.js. + +Conan uses ``os=Emscripten`` to: + +- Align with the toolchain: Emscripten integrates the compiler, runtime glue, and JavaScript environment, making it practical to treat as an "OS-like" target. + +- Support backward compatibility: Many recipes in Conan Center Index use ``os=Emscripten`` to enable or disable features and dependencies that specifically target Emscripten. + +- Maintain stability: Changing this setting would break recipes that rely on it, and would complicate compatibility with alternative WASM toolchains. + + +.. 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. + +.. important:: + + According to `emscripten documentation `_ Emscripten supports two multithreading APIs: + + - POSIX Threads API (``posix`` in conan profile) + - Wasm Workers API (``wasm_workers`` in conan profile) + + These two APIs are incompatible with each other and incompatibles with binaries compiled without threading support. + This incompatibility necessitates the modeling of threading usage within + the compiler's binary model, allowing conan to distinguish between binaries + compiled with threading and those compiled without it. + + Conan will automatically set compiler and linker flags to enable threading if configured in the profile. + + +The profiles above use the ``emsdk`` package from `Conan Center Index repository `_, 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, ``tool_requires`` could be replaced by custom ``compiler_executables`` and ``buildenv``: + +.. code-block:: text + + [conf] + tools.build:compiler_executables={'c':'/path/to/emcc', 'cpp':'/path/to/em++'} + + [buildenv] + CC=emcc + CXX=em++ + AR=emar + NM=emnm + RANLIB=emranlib + STRIP=emstrip + + +This way conan could configure `emsdk` local installation to be used from `CMake`, `Meson`, `Autotools` or other build systems. + +In some cases, you might also need the ``Emscripten.cmake`` toolchain file +for advanced scenarios. This toolchais is already added in our packaged +`emsdk` but if you are using your own Emscripten installation, you can +specify it in the profile by using +:ref:`tools.cmake.cmaketoolchain:user_toolchain` +and providing the absolute path to your toolchain file. + +.. note:: + + The ``tools.build:exelinkflags`` and ``tools.build:sharedlinkflags`` in + previous profiles are recomendations but users can modify them or define + their values in the CMakeLists.txt file using the + ``set_target_properties()`` command. + + - By enabling ``ALLOW_MEMORY_GROWTH`` we allow the runtime to grow its + memory dynamically at runtime by calling ``emscripten_resize_heap()``. Without + this flag, memory is allocated at startup and cannot grow. + + - The ``MAXIMUM_MEMORY`` and ``INITIAL_MEMORY`` values specifies the maximum + and initial memory size for the Emscripten runtime. These values can be + adjusted based on your application's needs. + + Take into account that ``arch=wasm64`` has a theorical exabytes maximum + memory size, but runtime currently limits it to 16GB, while ``arch=wasm32`` + has a maximum memory size of 4GB and ``arch=asm.js`` has a maximum memory size of 2GB. + + +.. important:: + + ``emcc`` compiler does not guarantee any ABI compatibility between different versions (patches included) + To ensure a new ``package_id`` is generated when the Emscripten version + changes, it is recommended to update the ``compiler.version`` setting in your profile accordingly. + + This will ensure that the package ID is generated based on the Emscripten + version, allowing Conan to detect changes in the Emscripten toolchain and + rebuild the project accordingly. diff --git a/images/integrations/conan-emscripten-logo.png b/images/integrations/conan-emscripten-logo.png new file mode 100644 index 000000000000..1e072247333f Binary files /dev/null and b/images/integrations/conan-emscripten-logo.png differ diff --git a/integrations.rst b/integrations.rst index f1cc644d4516..7256f35e3a4f 100644 --- a/integrations.rst +++ b/integrations.rst @@ -22,6 +22,7 @@ Xcode. integrations/makefile integrations/xcode integrations/meson + integrations/emscripten integrations/premake integrations/android integrations/jfrog diff --git a/integrations/emscripten.rst b/integrations/emscripten.rst new file mode 100644 index 000000000000..ed236858711a --- /dev/null +++ b/integrations/emscripten.rst @@ -0,0 +1,14 @@ +.. _integrations_emscripten: + +|emscripten_logo| Emscripten +============================ + +Conan provides support for cross-building for both `asm.js `_ and `WASM `_ (Web Assembly) targets +using `Emscripten `__. This enables developers to compile C/C++ code for the browser +and other JavaScript environments. + +For detailed examples and step-by-step instructions, refer to: + +- :ref:`Cross-building with Emscripten ` + +.. |emscripten_logo| image:: ../images/integrations/conan-emscripten-logo.png diff --git a/reference/tools/cmake/cmaketoolchain.rst b/reference/tools/cmake/cmaketoolchain.rst index f81ac957827e..d87a582f9156 100644 --- a/reference/tools/cmake/cmaketoolchain.rst +++ b/reference/tools/cmake/cmaketoolchain.rst @@ -364,6 +364,9 @@ If for some reason using absolute paths was desired, it is possible to do it wit tc.generate() + +.. _conan_cmake_user_toolchain: + Using a custom toolchain file ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^