From d45160751456dd6f0c688cfe34e4ec19efdcdbe9 Mon Sep 17 00:00:00 2001 From: PerseoGI Date: Fri, 30 May 2025 14:17:15 +0200 Subject: [PATCH 01/11] Added examples for WASM arch --- .../cross_build/wasm/bindigs/CMakeLists.txt | 30 ++ examples/cross_build/wasm/bindigs/README.md | 26 ++ .../cross_build/wasm/bindigs/conanfile.py | 45 +++ examples/cross_build/wasm/bindigs/main.cpp | 57 ++++ examples/cross_build/wasm/bindigs/shell.html | 157 ++++++++++ examples/cross_build/wasm/profiles/wasm32 | 26 ++ examples/cross_build/wasm/profiles/wasm64 | 31 ++ .../cross_build/wasm/wasm64/CMakeLists.txt | 4 + examples/cross_build/wasm/wasm64/README.md | 54 ++++ examples/cross_build/wasm/wasm64/conanfile.py | 23 ++ examples/cross_build/wasm/wasm64/main.cpp | 34 +++ .../cross_build/wasm/wasm_game/CMakeLists.txt | 14 + examples/cross_build/wasm/wasm_game/README.md | 15 + .../cross_build/wasm/wasm_game/conanfile.py | 18 ++ examples/cross_build/wasm/wasm_game/main.cpp | 108 +++++++ .../cross_build/wasm/wasm_game/shell.html | 267 ++++++++++++++++++ 16 files changed, 909 insertions(+) create mode 100644 examples/cross_build/wasm/bindigs/CMakeLists.txt create mode 100644 examples/cross_build/wasm/bindigs/README.md create mode 100644 examples/cross_build/wasm/bindigs/conanfile.py create mode 100644 examples/cross_build/wasm/bindigs/main.cpp create mode 100644 examples/cross_build/wasm/bindigs/shell.html create mode 100644 examples/cross_build/wasm/profiles/wasm32 create mode 100644 examples/cross_build/wasm/profiles/wasm64 create mode 100644 examples/cross_build/wasm/wasm64/CMakeLists.txt create mode 100644 examples/cross_build/wasm/wasm64/README.md create mode 100644 examples/cross_build/wasm/wasm64/conanfile.py create mode 100644 examples/cross_build/wasm/wasm64/main.cpp create mode 100644 examples/cross_build/wasm/wasm_game/CMakeLists.txt create mode 100644 examples/cross_build/wasm/wasm_game/README.md create mode 100644 examples/cross_build/wasm/wasm_game/conanfile.py create mode 100644 examples/cross_build/wasm/wasm_game/main.cpp create mode 100644 examples/cross_build/wasm/wasm_game/shell.html diff --git a/examples/cross_build/wasm/bindigs/CMakeLists.txt b/examples/cross_build/wasm/bindigs/CMakeLists.txt new file mode 100644 index 00000000..1c205b26 --- /dev/null +++ b/examples/cross_build/wasm/bindigs/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 3.15) +project(wasm_example CXX) + +find_package(Eigen3 REQUIRED) +add_executable(wasm_example main.cpp) + +target_link_libraries(${PROJECT_NAME} PRIVATE Eigen3::Eigen) + +install(TARGETS wasm_example DESTINATION "." + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + ) + +# Required for Emscripten + embind +set(CMAKE_EXECUTABLE_SUFFIX ".html") + +# set_target_properties(wasm_example PROPERTIES +# LINK_FLAGS "-sEXPORTED_FUNCTIONS=['_malloc','_free'] -sEXPORTED_RUNTIME_METHODS=['ccall','cwrap','getValue','setValue'] -sENVIRONMENT=web -sALLOW_MEMORY_GROWTH=1 -sNO_EXIT_RUNTIME=1 --shell-file ${CMAKE_SOURCE_DIR}/shell.html" +# ) + +set_target_properties(wasm_example PROPERTIES + LINK_FLAGS + "-sEXPORTED_FUNCTIONS=['_malloc','_free'] \ + -sEXPORTED_RUNTIME_METHODS=['ccall','cwrap','getValue','setValue'] \ + -sENVIRONMENT=web \ + -sALLOW_MEMORY_GROWTH=1 \ + -sNO_EXIT_RUNTIME=1 \ + --shell-file ${CMAKE_SOURCE_DIR}/shell.html" +) diff --git a/examples/cross_build/wasm/bindigs/README.md b/examples/cross_build/wasm/bindigs/README.md new file mode 100644 index 00000000..848ace87 --- /dev/null +++ b/examples/cross_build/wasm/bindigs/README.md @@ -0,0 +1,26 @@ +# WASM project with bindings and conan dependency + + +## Build and run + +To compile the project: + +```sh +$ conan build . -pr:h ../profiles/wasm32 --build=missing +``` + +To open a WASM webpage locally, most of the browsers will complain due to security reasons as WASM must be loaded asynchronous + +The easiest way of opening the generated webpage (should be in `build/release-wasm/wasm_example.html`) is by running a local server. +This can be done via `emrun` command (needs to be downloaded): + +```sh +$ emrun --browser build/release-wasm/wasm_example.html +``` + +Or using python `http.server` module: + +```sh +$ python -m http.server 8080 +``` +Then, navigating to your build folder and open `wasm_example.html` diff --git a/examples/cross_build/wasm/bindigs/conanfile.py b/examples/cross_build/wasm/bindigs/conanfile.py new file mode 100644 index 00000000..cf73bfbf --- /dev/null +++ b/examples/cross_build/wasm/bindigs/conanfile.py @@ -0,0 +1,45 @@ +import os + +from conan import ConanFile +from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout +from conan.tools.files import copy + + +class WasmExampleRecipe(ConanFile): + name = "wasm-example" + version = "1.0" + package_type = "application" + + # Optional metadata + license = "" + author = " " + url = "" + description = "" + topics = ("", "", "") + + # Binary configuration + settings = "os", "compiler", "build_type", "arch" + + # Sources are located in the same place as this recipe, copy them to the recipe + exports_sources = "CMakeLists.txt", "src/*" + + def layout(self): + cmake_layout(self) + + def requirements(self): + self.requires("eigen/3.4.0") + + def generate(self): + deps = CMakeDeps(self) + deps.generate() + tc = CMakeToolchain(self) + tc.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def package(self): + cmake = CMake(self) + cmake.install() diff --git a/examples/cross_build/wasm/bindigs/main.cpp b/examples/cross_build/wasm/bindigs/main.cpp new file mode 100644 index 00000000..93f43d03 --- /dev/null +++ b/examples/cross_build/wasm/bindigs/main.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include + +#ifdef __cplusplus +#define EXTERN extern "C" +#else +#define EXTERN +#endif + + +EXTERN EMSCRIPTEN_KEEPALIVE +uint32_t fib(uint32_t n) { + std::cout << "Calculating Fibonacci for n = " << n << std::endl; + if (n <= 1) return n; + uint32_t a = 0, b = 1, c; + for (uint32_t i = 2; i <= n; ++i) { + c = a + b; + a = b; + b = c; + } + return c; +} + +EXTERN EMSCRIPTEN_KEEPALIVE +void printMessage(const char* message) { + std::cout << "Message from C: " << message << std::endl; + std::string script = "alert('Message from C++: " + std::string(message) + "')"; + std::cout << "Executing script: " << script << std::endl; + emscripten_run_script(script.c_str()); +} + +EXTERN EMSCRIPTEN_KEEPALIVE +void addOne(int32_t *input, int32_t *output){ + *output = *input + 1; +} + +EXTERN EMSCRIPTEN_KEEPALIVE +float sumArray(const float* data, int32_t size) { + // print data input + std::cout << "Data input: "; + for (int i = 0; i < size; ++i) { + std::cout << data[i] << " "; + } + std::cout << std::endl; + Eigen::Map vec(data, size); + return vec.sum(); +} + + +int main() { + std::cout << "Hello World!" << std::endl; + auto data = new float[5]{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; + std::cout << sumArray(data, 5) << std::endl; +} diff --git a/examples/cross_build/wasm/bindigs/shell.html b/examples/cross_build/wasm/bindigs/shell.html new file mode 100644 index 00000000..5ec5b802 --- /dev/null +++ b/examples/cross_build/wasm/bindigs/shell.html @@ -0,0 +1,157 @@ + + + +

Conan C++ WebAssembly Example

+
+
Downloading...
+
+ +
+ +
+ + + +
+ + + + +

+
+ + + +

+
+ + + + +

+ + + {{{ SCRIPT }}} + + diff --git a/examples/cross_build/wasm/profiles/wasm32 b/examples/cross_build/wasm/profiles/wasm32 new file mode 100644 index 00000000..6ef908d2 --- /dev/null +++ b/examples/cross_build/wasm/profiles/wasm32 @@ -0,0 +1,26 @@ +[settings] +arch=wasm +build_type=Release +compiler=apple-clang +compiler.cppstd=gnu17 +compiler.cstd=gnu11 +compiler.libcxx=libc++ +compiler.version=17 +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' ] + +# Uncomment the following line to use emcc and em++ system compilers instead of conan packaged ones +# tools.build:compiler_executables={'c':'emcc', 'cpp':'em++'} + +# Verbosity +tools.build:verbosity=verbose +tools.compilation:verbosity=verbose + +# Distinguish between wasm32 and wasm64 architecture +tools.cmake.cmake_layout:build_folder_vars=['settings.build_type', 'settings.arch'] diff --git a/examples/cross_build/wasm/profiles/wasm64 b/examples/cross_build/wasm/profiles/wasm64 new file mode 100644 index 00000000..afbf069d --- /dev/null +++ b/examples/cross_build/wasm/profiles/wasm64 @@ -0,0 +1,31 @@ +[settings] +arch=wasm64 +build_type=Release +compiler=apple-clang +compiler.cppstd=gnu17 +compiler.cstd=gnu11 +compiler.libcxx=libc++ +compiler.version=17 +os=Emscripten + +[tool_requires] +emsdk/[*] + +[conf] +tools.build:cflags=['-sMEMORY64=1'] +tools.build:cxxflags=['-sMEMORY64=1'] + +# In this early stage of wasm64, ALLOW_MEMORY_GROWTH is not having effect. Also it may not be the most efficient solution. +# wasm64 for now needs to declare INITIAL_MEMORY as the maximum memory +tools.build:exelinkflags=[ '-sMEMORY64=1', '-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB' ] +tools.build:sharedlinkflags=[ '-sMEMORY64=1', '-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB' ] + +# Uncomment the following line to use emcc and em++ system compilers instead of conan packaged ones +# tools.build:compiler_executables={'c':'emcc', 'cpp':'em++'} + +# General config +tools.build:verbosity=verbose +tools.compilation:verbosity=verbose + +# Distinguish between wasm32 and wasm64 architecture +tools.cmake.cmake_layout:build_folder_vars=['settings.build_type', 'settings.arch'] diff --git a/examples/cross_build/wasm/wasm64/CMakeLists.txt b/examples/cross_build/wasm/wasm64/CMakeLists.txt new file mode 100644 index 00000000..f6a48836 --- /dev/null +++ b/examples/cross_build/wasm/wasm64/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.15) +project(wasm-alloc CXX) + +add_executable(wasm-alloc main.cpp) diff --git a/examples/cross_build/wasm/wasm64/README.md b/examples/cross_build/wasm/wasm64/README.md new file mode 100644 index 00000000..7437c87c --- /dev/null +++ b/examples/cross_build/wasm/wasm64/README.md @@ -0,0 +1,54 @@ +# WASM 32 bit vs 64 bit projet comparison + + +This basic example aims to show the differences between cross compiling a project with `arch=wasm` (which stands for `wasm32` bits) +and `arch=wasm64` the newly introduced architecture which supports WebAssembly 64-bits. + + +To compile the project in 32 bits follow this instructions: + +```sh +$ conan build . -pr ../profiles/wasm32 +$ node build/release-wasm/wasm-alloc.js + +Current allocated: 1 GiB +Current allocated: 2 GiB +Current allocated: 3 GiB +Failed after allocating 4064 MiB ~ 3 GiB +``` + +As we can see, in 32 bits mode, we can allocate up to 4 GB of dynamic memory. This is a limitation of `wasm32` architecture. +I we take a look at the `wasm32` profile, we can see `sMAXIMUM_MEMORY=4GB`. Trying to increase this number will result in a compilation error similar to this one: + +``` +wasm-ld: error: maximum memory too large, cannot be greater than 4294967296 +``` + +This is the main reason for `wasm64` to exist. Mind than `wasm64` is still under development: +To compile this project in `64 bit` mode, run the following commands: + +```sh +$ conan build . -pr ../profiles/wasm64 +$ node build/release-wasm64/wasm-alloc.js + +Current allocated: 1 GiB +Current allocated: 2 GiB +Current allocated: 3 GiB +Current allocated: 4 GiB +Current allocated: 5 GiB +Current allocated: 6 GiB +Current allocated: 7 GiB +Current allocated: 8 GiB +Current allocated: 9 GiB +Current allocated: 10 GiB +Current allocated: 11 GiB +Current allocated: 12 GiB +Current allocated: 13 GiB +Current allocated: 14 GiB +Current allocated: 15 GiB +Failed after allocating 16352 MiB ~ 15 GiB +``` + +The difference is notable, the 4 GB limitation does not exist more in a `64 bit` architecture. +The dynamic memory limit could be easily increased by modifying the profile. + diff --git a/examples/cross_build/wasm/wasm64/conanfile.py b/examples/cross_build/wasm/wasm64/conanfile.py new file mode 100644 index 00000000..a7453498 --- /dev/null +++ b/examples/cross_build/wasm/wasm64/conanfile.py @@ -0,0 +1,23 @@ +from conan import ConanFile +from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps + + +class WasmAllocatorRecipe(ConanFile): + name = "wasm-alloc" + version = "1.0" + package_type = "application" + settings = "os", "compiler", "build_type", "arch" + + def layout(self): + cmake_layout(self) + + def generate(self): + deps = CMakeDeps(self) + deps.generate() + tc = CMakeToolchain(self) + tc.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() diff --git a/examples/cross_build/wasm/wasm64/main.cpp b/examples/cross_build/wasm/wasm64/main.cpp new file mode 100644 index 00000000..408dfcf0 --- /dev/null +++ b/examples/cross_build/wasm/wasm64/main.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include + +int main() { + const size_t GIGABYTE = 1024 * 1024 * 1024; + const size_t CHUNK_SIZE = 32 * 1024 * 1024; // 32 MiB + std::vector allocations; + size_t total_allocated = 0; + + while (true) { + char* block = static_cast(malloc(CHUNK_SIZE)); + if (!block) { + std::cerr << "Failed after allocating " << total_allocated / (1024 * 1024) << " MiB ~ " << total_allocated / GIGABYTE << " GiB" << std::endl; + break; + } + + // Touch memory to ensure it's actually committed (not lazy-allocated) + std::memset(block, 0xAB, CHUNK_SIZE); + allocations.push_back(block); + total_allocated += CHUNK_SIZE; + if (total_allocated % GIGABYTE == 0) { + std::cout << "Current allocated: " << total_allocated / GIGABYTE << " GiB" << std::endl; + } + } + + // Free the memory afterward + for (char* ptr : allocations) { + free(ptr); + } + + return 0; +} diff --git a/examples/cross_build/wasm/wasm_game/CMakeLists.txt b/examples/cross_build/wasm/wasm_game/CMakeLists.txt new file mode 100644 index 00000000..b326c0a6 --- /dev/null +++ b/examples/cross_build/wasm/wasm_game/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.23) +project(wasm_game) + +set(CMAKE_CXX_STANDARD 17) +find_package(raylib) + +add_executable(wasm_game main.cpp) +target_link_libraries(wasm_game raylib) + +set(CMAKE_EXECUTABLE_SUFFIX ".html") + +set_target_properties(wasm_game PROPERTIES + LINK_FLAGS "-sALLOW_MEMORY_GROWTH=1 -sUSE_GLFW=3 -sASYNCIFY --shell-file ${CMAKE_SOURCE_DIR}/shell.html" +) diff --git a/examples/cross_build/wasm/wasm_game/README.md b/examples/cross_build/wasm/wasm_game/README.md new file mode 100644 index 00000000..f8824b56 --- /dev/null +++ b/examples/cross_build/wasm/wasm_game/README.md @@ -0,0 +1,15 @@ +# WASM simple game + +This project is a copy of our [raylib](https://github.com/conan-io/examples2/tree/main/examples/libraries/raylib/introduction) example project. + +It has minor modifications: + +- C++ source code has been modified in order to accept mouse clicks as inputs as it is more convenient for a webpage +- `CMakeLists.txt` has been modified in order to link against raylib correctly using WASM + - `-sUSE_GLFW=3 -sASYNCIFY`: see [raylib web manual](https://github.com/raysan5/raylib/wiki/Working-for-Web-(HTML5)#23-using-cmake) for a deeper explanation + - `--shell-file`: generate the html code from the template + + +## Build and run + +See instructions in [bindings example](https://github.com/conan-io/examples2/tree/main/examples/cross_build/wasm/bindings) diff --git a/examples/cross_build/wasm/wasm_game/conanfile.py b/examples/cross_build/wasm/wasm_game/conanfile.py new file mode 100644 index 00000000..ff359fb7 --- /dev/null +++ b/examples/cross_build/wasm/wasm_game/conanfile.py @@ -0,0 +1,18 @@ +from conan import ConanFile +from conan.tools.cmake import CMake, cmake_layout + +class ConanApplication(ConanFile): + package_type = "application" + settings = "os", "compiler", "build_type", "arch" + generators = "CMakeDeps", "CMakeToolchain" + + def layout(self): + cmake_layout(self) + + def requirements(self): + self.requires("raylib/5.5") + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() diff --git a/examples/cross_build/wasm/wasm_game/main.cpp b/examples/cross_build/wasm/wasm_game/main.cpp new file mode 100644 index 00000000..c35af2b0 --- /dev/null +++ b/examples/cross_build/wasm/wasm_game/main.cpp @@ -0,0 +1,108 @@ +#include +#include "raylib.h" + +int main() { + // --- Initialization --- + const int screenW = 800; + const int screenH = 350; + InitWindow(screenW, screenH, "Jump to Survive!"); + + // --- Player Setup --- + Rectangle player = { 100, screenH - 80, 40, 60 }; + float vy = 0; + const float gravity = 1000.0f; + const float jumpImpulse = -450.0f; + + // --- Ground Definition --- + const int groundY = screenH - 20; + + // --- Obstacle Management --- + std::vector obstacles; + float spawnTimer = 0.0f; + float spawnInterval = 1.2f; + const float obstacleSpeed = 300.0f; + + const float minSpawnInterval = 0.8f; + const float maxSpawnInterval = 1.6f; + + const int minObsWidth = 40; + const int maxObsWidth = 120; + + // --- Game State Variables --- + int score = 0; + bool gameOver = false; + + SetTargetFPS(60); + + while (!WindowShouldClose()) { + float dt = GetFrameTime(); + + if (!gameOver) { + // Jump logic + if ((IsKeyPressed(KEY_SPACE) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) && player.y + player.height >= groundY) { + vy = jumpImpulse; + } + vy += gravity * dt; + player.y += vy * dt; + if (player.y + player.height > groundY) { + player.y = groundY - player.height; + vy = 0; + } + + // Spawn obstacles with random width & interval + spawnTimer += dt; + if (spawnTimer >= spawnInterval) { + spawnTimer = 0.0f; + // recalc next interval + spawnInterval = GetRandomValue(int(minSpawnInterval*100), int(maxSpawnInterval*100)) / 100.0f; + // random width + int w = GetRandomValue(minObsWidth, maxObsWidth); + obstacles.push_back({ float(screenW), float(groundY - 40), float(w), 40.0f }); + } + + // Move & collide obstacles + for (int i = 0; i < (int)obstacles.size(); i++) { + obstacles[i].x -= obstacleSpeed * dt; + if (CheckCollisionRecs(player, obstacles[i])) { + gameOver = true; + } + } + // Remove off-screen & score + if (!obstacles.empty() && obstacles.front().x + obstacles.front().width < 0) { + obstacles.erase(obstacles.begin()); + score++; + } + } + else { + if (IsKeyPressed(KEY_R) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { + // reset everything + player.y = screenH - 80; + vy = 0; + obstacles.clear(); + spawnTimer = 0.0f; + spawnInterval = 1.2f; + score = 0; + gameOver = false; + } + } + + // --- Drawing --- + BeginDrawing(); + ClearBackground(RAYWHITE); + + DrawRectangle(0, groundY, screenW, 20, DARKGRAY); + DrawRectangleRec(player, BLUE); + for (auto &obs : obstacles) DrawRectangleRec(obs, RED); + + DrawText(TextFormat("Score: %d", score), 10, 10, 20, BLACK); + + if (gameOver) { + DrawText("GAME OVER! Press R or left click to restart", 180, screenH/2 - 20, 20, MAROON); + } + + EndDrawing(); + } + + CloseWindow(); + return 0; +} diff --git a/examples/cross_build/wasm/wasm_game/shell.html b/examples/cross_build/wasm/wasm_game/shell.html new file mode 100644 index 00000000..f5818562 --- /dev/null +++ b/examples/cross_build/wasm/wasm_game/shell.html @@ -0,0 +1,267 @@ + + + + + + + Conan WASM game example + + + + + + + + +
+ +
+ + + + + + + + {{{ SCRIPT }}} + + From a69d48c7bcdb59e33ca558e72a9831b1563407e0 Mon Sep 17 00:00:00 2001 From: PerseoGI Date: Mon, 2 Jun 2025 13:08:11 +0200 Subject: [PATCH 02/11] Update README.md Added game image --- examples/cross_build/wasm/wasm_game/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/cross_build/wasm/wasm_game/README.md b/examples/cross_build/wasm/wasm_game/README.md index f8824b56..30ccccee 100644 --- a/examples/cross_build/wasm/wasm_game/README.md +++ b/examples/cross_build/wasm/wasm_game/README.md @@ -9,6 +9,8 @@ It has minor modifications: - `-sUSE_GLFW=3 -sASYNCIFY`: see [raylib web manual](https://github.com/raysan5/raylib/wiki/Working-for-Web-(HTML5)#23-using-cmake) for a deeper explanation - `--shell-file`: generate the html code from the template +![image](https://github.com/user-attachments/assets/941b5922-edb6-400f-9d38-ba805fc8a3ab) + ## Build and run From b516bd24eea3a4d10a457ccc28f778d7b4e7c0ed Mon Sep 17 00:00:00 2001 From: PerseoGI Date: Mon, 2 Jun 2025 13:14:37 +0200 Subject: [PATCH 03/11] Formated and linted --- .../cross_build/wasm/bindigs/CMakeLists.txt | 4 -- examples/cross_build/wasm/bindigs/main.cpp | 62 +++++++++---------- examples/cross_build/wasm/bindigs/shell.html | 37 ++++++----- examples/cross_build/wasm/wasm64/main.cpp | 51 ++++++++------- 4 files changed, 76 insertions(+), 78 deletions(-) diff --git a/examples/cross_build/wasm/bindigs/CMakeLists.txt b/examples/cross_build/wasm/bindigs/CMakeLists.txt index 1c205b26..67d1f9c7 100644 --- a/examples/cross_build/wasm/bindigs/CMakeLists.txt +++ b/examples/cross_build/wasm/bindigs/CMakeLists.txt @@ -15,10 +15,6 @@ install(TARGETS wasm_example DESTINATION "." # Required for Emscripten + embind set(CMAKE_EXECUTABLE_SUFFIX ".html") -# set_target_properties(wasm_example PROPERTIES -# LINK_FLAGS "-sEXPORTED_FUNCTIONS=['_malloc','_free'] -sEXPORTED_RUNTIME_METHODS=['ccall','cwrap','getValue','setValue'] -sENVIRONMENT=web -sALLOW_MEMORY_GROWTH=1 -sNO_EXIT_RUNTIME=1 --shell-file ${CMAKE_SOURCE_DIR}/shell.html" -# ) - set_target_properties(wasm_example PROPERTIES LINK_FLAGS "-sEXPORTED_FUNCTIONS=['_malloc','_free'] \ diff --git a/examples/cross_build/wasm/bindigs/main.cpp b/examples/cross_build/wasm/bindigs/main.cpp index 93f43d03..f60f99e0 100644 --- a/examples/cross_build/wasm/bindigs/main.cpp +++ b/examples/cross_build/wasm/bindigs/main.cpp @@ -1,7 +1,7 @@ +#include #include #include #include -#include #include #ifdef __cplusplus @@ -10,46 +10,42 @@ #define EXTERN #endif - -EXTERN EMSCRIPTEN_KEEPALIVE -uint32_t fib(uint32_t n) { - std::cout << "Calculating Fibonacci for n = " << n << std::endl; - if (n <= 1) return n; - uint32_t a = 0, b = 1, c; - for (uint32_t i = 2; i <= n; ++i) { - c = a + b; - a = b; - b = c; - } - return c; +EXTERN EMSCRIPTEN_KEEPALIVE uint32_t fib(uint32_t n) { + std::cout << "Calculating Fibonacci for n = " << n << std::endl; + if (n <= 1) + return n; + uint32_t a = 0, b = 1, c; + for (uint32_t i = 2; i <= n; ++i) { + c = a + b; + a = b; + b = c; + } + return c; } -EXTERN EMSCRIPTEN_KEEPALIVE -void printMessage(const char* message) { - std::cout << "Message from C: " << message << std::endl; - std::string script = "alert('Message from C++: " + std::string(message) + "')"; - std::cout << "Executing script: " << script << std::endl; - emscripten_run_script(script.c_str()); +EXTERN EMSCRIPTEN_KEEPALIVE void printMessage(const char *message) { + std::cout << "Message from C: " << message << std::endl; + std::string script = + "alert('Message from C++: " + std::string(message) + "')"; + std::cout << "Executing script: " << script << std::endl; + emscripten_run_script(script.c_str()); } -EXTERN EMSCRIPTEN_KEEPALIVE -void addOne(int32_t *input, int32_t *output){ - *output = *input + 1; +EXTERN EMSCRIPTEN_KEEPALIVE void addOne(int32_t *input, int32_t *output) { + *output = *input + 1; } -EXTERN EMSCRIPTEN_KEEPALIVE -float sumArray(const float* data, int32_t size) { - // print data input - std::cout << "Data input: "; - for (int i = 0; i < size; ++i) { - std::cout << data[i] << " "; - } - std::cout << std::endl; - Eigen::Map vec(data, size); - return vec.sum(); +EXTERN EMSCRIPTEN_KEEPALIVE float sumArray(const float *data, int32_t size) { + // print data input + std::cout << "Data input: "; + for (int i = 0; i < size; ++i) { + std::cout << data[i] << " "; + } + std::cout << std::endl; + Eigen::Map vec(data, size); + return vec.sum(); } - int main() { std::cout << "Hello World!" << std::endl; auto data = new float[5]{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; diff --git a/examples/cross_build/wasm/bindigs/shell.html b/examples/cross_build/wasm/bindigs/shell.html index 5ec5b802..747675e2 100644 --- a/examples/cross_build/wasm/bindigs/shell.html +++ b/examples/cross_build/wasm/bindigs/shell.html @@ -96,7 +96,7 @@

Conan C++ WebAssembly Example

// Example of auto string handle by WASM on simple string parameter passing const printMessage = () => { - var printer = Module.ccall( + Module.ccall( "printMessage", null, ["string"], @@ -106,48 +106,51 @@

Conan C++ WebAssembly Example

// Example of a simple invocation to fibonachi const fibExample = () => { - var fib = Module.cwrap("fib", "number", ["number"]); // returns a number - var input = parseInt(document.getElementById("fibInput").value); + const fib = Module.cwrap("fib", "number", ["number"]); // returns a number + const input = parseInt(document.getElementById("fibInput").value); if (isNaN(input)) { alert("Please enter a valid integer."); return; } - var result = fib(input); + const result = fib(input); document.getElementById("fibResult").textContent = "Fibonacci of " + input + " is: " + result; }; var value = 0; // (static) value to increment by one const pressBtn = () => { - var addOne = Module.cwrap("addOne", null, ["number", "number"]); // void function + const addOne = Module.cwrap("addOne", null, ["number", "number"]); // void function // alloc 4 bytes of memory for the input and 4 for the output (32-bit integers) - var input_ptr = Module._malloc(4); - var output_ptr = Module._malloc(4); + const inputPtr = Module._malloc(4); + const outputPtr = Module._malloc(4); - Module.setValue(input_ptr, value, "i32"); // set the value in WASM memory - addOne(input_ptr, output_ptr); // call the WASM function - var result = Module.getValue(output_ptr, "i32"); // extract the result from WASM memory + Module.setValue(inputPtr, value, "i32"); + addOne(inputPtr, outputPtr); + const result = Module.getValue(outputPtr, "i32"); value = result; document.getElementById("counterResult").textContent = "Sum: " + result; // dealloc memory to avoid memory leaks - Module._free(input_ptr); - Module._free(output_ptr); + Module._free(inputPtr); + Module._free(outputPtr); }; const sumExample = () => { - var sumArray = Module.cwrap("sumArray", "number", ["number", "number"]); + const sumArray = Module.cwrap("sumArray", "number", [ + "number", + "number", + ]); // Get the input string and split by commas const inputStr = document.getElementById("numbersInput").value; const numberStrings = inputStr.split(",").map((s) => s.trim()); // Convert to Float32Array const inputArray = new Float32Array(numberStrings.map(Number)); - var len = inputArray.length; - var bytesPerElement = inputArray.BYTES_PER_ELEMENT; - var inputPtr = Module._malloc(len * bytesPerElement); + const len = inputArray.length; + const bytesPerElement = inputArray.BYTES_PER_ELEMENT; + const inputPtr = Module._malloc(len * bytesPerElement); Module.HEAPF32.set(inputArray, inputPtr / bytesPerElement); - var result = sumArray(inputPtr, len); + const result = sumArray(inputPtr, len); Module._free(inputPtr); document.getElementById("sumResult").textContent = "Sum: " + result; }; diff --git a/examples/cross_build/wasm/wasm64/main.cpp b/examples/cross_build/wasm/wasm64/main.cpp index 408dfcf0..f7b30c16 100644 --- a/examples/cross_build/wasm/wasm64/main.cpp +++ b/examples/cross_build/wasm/wasm64/main.cpp @@ -1,34 +1,37 @@ -#include -#include #include #include +#include +#include int main() { - const size_t GIGABYTE = 1024 * 1024 * 1024; - const size_t CHUNK_SIZE = 32 * 1024 * 1024; // 32 MiB - std::vector allocations; - size_t total_allocated = 0; - - while (true) { - char* block = static_cast(malloc(CHUNK_SIZE)); - if (!block) { - std::cerr << "Failed after allocating " << total_allocated / (1024 * 1024) << " MiB ~ " << total_allocated / GIGABYTE << " GiB" << std::endl; - break; - } + const size_t GIGABYTE = 1024 * 1024 * 1024; + const size_t CHUNK_SIZE = 32 * 1024 * 1024; // 32 MiB + std::vector allocations; + size_t total_allocated = 0; - // Touch memory to ensure it's actually committed (not lazy-allocated) - std::memset(block, 0xAB, CHUNK_SIZE); - allocations.push_back(block); - total_allocated += CHUNK_SIZE; - if (total_allocated % GIGABYTE == 0) { - std::cout << "Current allocated: " << total_allocated / GIGABYTE << " GiB" << std::endl; - } + while (true) { + char *block = static_cast(malloc(CHUNK_SIZE)); + if (!block) { + std::cerr << "Failed after allocating " << total_allocated / (1024 * 1024) + << " MiB ~ " << total_allocated / GIGABYTE << " GiB" + << std::endl; + break; } - // Free the memory afterward - for (char* ptr : allocations) { - free(ptr); + // Touch memory to ensure it's actually committed (not lazy-allocated) + std::memset(block, 0xAB, CHUNK_SIZE); + allocations.push_back(block); + total_allocated += CHUNK_SIZE; + if (total_allocated % GIGABYTE == 0) { + std::cout << "Current allocated: " << total_allocated / GIGABYTE << " GiB" + << std::endl; } + } + + // Free the memory afterward + for (char *ptr : allocations) { + free(ptr); + } - return 0; + return 0; } From e8c9be628954366fcfadfc7d287f345dc89222d1 Mon Sep 17 00:00:00 2001 From: PerseoGI Date: Tue, 3 Jun 2025 10:15:07 +0200 Subject: [PATCH 04/11] Fix bindings name and updated profiles --- .../wasm/{bindigs => bindings}/CMakeLists.txt | 0 .../wasm/{bindigs => bindings}/README.md | 0 .../wasm/{bindigs => bindings}/conanfile.py | 0 .../wasm/{bindigs => bindings}/main.cpp | 0 .../wasm/{bindigs => bindings}/shell.html | 0 examples/cross_build/wasm/profiles/wasm64 | 7 ++----- examples/cross_build/wasm/wasm64/README.md | 18 +++++++++++++++++- .../cross_build/wasm/wasm_game/CMakeLists.txt | 7 +++---- .../cross_build/wasm/wasm_game/conanfile.py | 13 +++++++++++-- 9 files changed, 33 insertions(+), 12 deletions(-) rename examples/cross_build/wasm/{bindigs => bindings}/CMakeLists.txt (100%) rename examples/cross_build/wasm/{bindigs => bindings}/README.md (100%) rename examples/cross_build/wasm/{bindigs => bindings}/conanfile.py (100%) rename examples/cross_build/wasm/{bindigs => bindings}/main.cpp (100%) rename examples/cross_build/wasm/{bindigs => bindings}/shell.html (100%) diff --git a/examples/cross_build/wasm/bindigs/CMakeLists.txt b/examples/cross_build/wasm/bindings/CMakeLists.txt similarity index 100% rename from examples/cross_build/wasm/bindigs/CMakeLists.txt rename to examples/cross_build/wasm/bindings/CMakeLists.txt diff --git a/examples/cross_build/wasm/bindigs/README.md b/examples/cross_build/wasm/bindings/README.md similarity index 100% rename from examples/cross_build/wasm/bindigs/README.md rename to examples/cross_build/wasm/bindings/README.md diff --git a/examples/cross_build/wasm/bindigs/conanfile.py b/examples/cross_build/wasm/bindings/conanfile.py similarity index 100% rename from examples/cross_build/wasm/bindigs/conanfile.py rename to examples/cross_build/wasm/bindings/conanfile.py diff --git a/examples/cross_build/wasm/bindigs/main.cpp b/examples/cross_build/wasm/bindings/main.cpp similarity index 100% rename from examples/cross_build/wasm/bindigs/main.cpp rename to examples/cross_build/wasm/bindings/main.cpp diff --git a/examples/cross_build/wasm/bindigs/shell.html b/examples/cross_build/wasm/bindings/shell.html similarity index 100% rename from examples/cross_build/wasm/bindigs/shell.html rename to examples/cross_build/wasm/bindings/shell.html diff --git a/examples/cross_build/wasm/profiles/wasm64 b/examples/cross_build/wasm/profiles/wasm64 index afbf069d..44b406f5 100644 --- a/examples/cross_build/wasm/profiles/wasm64 +++ b/examples/cross_build/wasm/profiles/wasm64 @@ -12,13 +12,10 @@ os=Emscripten emsdk/[*] [conf] -tools.build:cflags=['-sMEMORY64=1'] -tools.build:cxxflags=['-sMEMORY64=1'] - # In this early stage of wasm64, ALLOW_MEMORY_GROWTH is not having effect. Also it may not be the most efficient solution. # wasm64 for now needs to declare INITIAL_MEMORY as the maximum memory -tools.build:exelinkflags=[ '-sMEMORY64=1', '-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB' ] -tools.build:sharedlinkflags=[ '-sMEMORY64=1', '-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB' ] +tools.build:exelinkflags=['-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB'] +tools.build:sharedlinkflags=['-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB'] # Uncomment the following line to use emcc and em++ system compilers instead of conan packaged ones # tools.build:compiler_executables={'c':'emcc', 'cpp':'em++'} diff --git a/examples/cross_build/wasm/wasm64/README.md b/examples/cross_build/wasm/wasm64/README.md index 7437c87c..d7f3ee70 100644 --- a/examples/cross_build/wasm/wasm64/README.md +++ b/examples/cross_build/wasm/wasm64/README.md @@ -1,4 +1,4 @@ -# WASM 32 bit vs 64 bit projet comparison +# WASM 32 bit vs 64 bit project comparison This basic example aims to show the differences between cross compiling a project with `arch=wasm` (which stands for `wasm32` bits) @@ -52,3 +52,19 @@ Failed after allocating 16352 MiB ~ 15 GiB The difference is notable, the 4 GB limitation does not exist more in a `64 bit` architecture. The dynamic memory limit could be easily increased by modifying the profile. + +## Binary inspection + +Another way of determining if a WASM lib is 32 or 64 bit, `wasm-objdump` command can be used (must be downloaded first): + +```sh +$ wasm-objdump -d build/release-wasm/wasm-alloc.wasm | grep '\.load' +``` +This should output `i32.load`. + +But the following should show plenty of `i64.load`, indicating `64-bit` operations: + +```sh +$ wasm-objdump -d build/release-wasm64/wasm-alloc.wasm | grep '\.load' +``` + diff --git a/examples/cross_build/wasm/wasm_game/CMakeLists.txt b/examples/cross_build/wasm/wasm_game/CMakeLists.txt index b326c0a6..765a71f6 100644 --- a/examples/cross_build/wasm/wasm_game/CMakeLists.txt +++ b/examples/cross_build/wasm/wasm_game/CMakeLists.txt @@ -7,8 +7,7 @@ find_package(raylib) add_executable(wasm_game main.cpp) target_link_libraries(wasm_game raylib) +# Set the executable suffix to .html in order to generate a html page by +# Emscripten (there is no way of setting this from a user toolchain or +# conanfile as it is later overriden by the emscripten toolchain) set(CMAKE_EXECUTABLE_SUFFIX ".html") - -set_target_properties(wasm_game PROPERTIES - LINK_FLAGS "-sALLOW_MEMORY_GROWTH=1 -sUSE_GLFW=3 -sASYNCIFY --shell-file ${CMAKE_SOURCE_DIR}/shell.html" -) diff --git a/examples/cross_build/wasm/wasm_game/conanfile.py b/examples/cross_build/wasm/wasm_game/conanfile.py index ff359fb7..b96ecf26 100644 --- a/examples/cross_build/wasm/wasm_game/conanfile.py +++ b/examples/cross_build/wasm/wasm_game/conanfile.py @@ -1,10 +1,9 @@ from conan import ConanFile -from conan.tools.cmake import CMake, cmake_layout +from conan.tools.cmake import CMake, cmake_layout, CMakeDeps, CMakeToolchain class ConanApplication(ConanFile): package_type = "application" settings = "os", "compiler", "build_type", "arch" - generators = "CMakeDeps", "CMakeToolchain" def layout(self): cmake_layout(self) @@ -12,6 +11,16 @@ def layout(self): def requirements(self): self.requires("raylib/5.5") + def generate(self): + deps = CMakeDeps(self) + deps.generate() + + tc = CMakeToolchain(self) + tc.extra_exelinkflags.append( + "-sALLOW_MEMORY_GROWTH=1 -sUSE_GLFW=3 -sASYNCIFY --shell-file=${CMAKE_SOURCE_DIR}/shell.html" + ) + tc.generate() + def build(self): cmake = CMake(self) cmake.configure() From 709e2f9c8828b4c4fc91f9d71a57fb6843c7db37 Mon Sep 17 00:00:00 2001 From: PerseoGI Date: Tue, 3 Jun 2025 11:50:20 +0200 Subject: [PATCH 05/11] Renamed bindings and updated profiles --- .../cross_build/wasm/bindings/CMakeLists.txt | 20 +++----------- .../wasm/bindings/ci_test_example.py | 8 ++++++ .../cross_build/wasm/bindings/conanfile.py | 26 +++++++------------ .../wasm/wasm64/ci_test_example.py | 17 ++++++++++++ .../cross_build/wasm/wasm_game/CMakeLists.txt | 2 +- examples/cross_build/wasm/wasm_game/README.md | 5 ++-- .../wasm/wasm_game/ci_test_example.py | 8 ++++++ 7 files changed, 50 insertions(+), 36 deletions(-) create mode 100644 examples/cross_build/wasm/bindings/ci_test_example.py create mode 100644 examples/cross_build/wasm/wasm64/ci_test_example.py create mode 100644 examples/cross_build/wasm/wasm_game/ci_test_example.py diff --git a/examples/cross_build/wasm/bindings/CMakeLists.txt b/examples/cross_build/wasm/bindings/CMakeLists.txt index 67d1f9c7..f8d76faf 100644 --- a/examples/cross_build/wasm/bindings/CMakeLists.txt +++ b/examples/cross_build/wasm/bindings/CMakeLists.txt @@ -6,21 +6,7 @@ add_executable(wasm_example main.cpp) target_link_libraries(${PROJECT_NAME} PRIVATE Eigen3::Eigen) -install(TARGETS wasm_example DESTINATION "." - RUNTIME DESTINATION bin - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - ) - -# Required for Emscripten + embind +# Set the executable suffix to .html in order to generate a html page by +# Emscripten (there is no way of setting this from a user toolchain or +# conanfile as it is later overridden by the Emscripten toolchain) set(CMAKE_EXECUTABLE_SUFFIX ".html") - -set_target_properties(wasm_example PROPERTIES - LINK_FLAGS - "-sEXPORTED_FUNCTIONS=['_malloc','_free'] \ - -sEXPORTED_RUNTIME_METHODS=['ccall','cwrap','getValue','setValue'] \ - -sENVIRONMENT=web \ - -sALLOW_MEMORY_GROWTH=1 \ - -sNO_EXIT_RUNTIME=1 \ - --shell-file ${CMAKE_SOURCE_DIR}/shell.html" -) diff --git a/examples/cross_build/wasm/bindings/ci_test_example.py b/examples/cross_build/wasm/bindings/ci_test_example.py new file mode 100644 index 00000000..bc30cbcd --- /dev/null +++ b/examples/cross_build/wasm/bindings/ci_test_example.py @@ -0,0 +1,8 @@ +import os +from test.examples_tools import run + +run("conan build . --build=missing --profile:host ../profiles/wasm32") + +assert os.path.exists(os.path.join("build", "release-wasm", "wasm_example.html")) +assert os.path.exists(os.path.join("build", "release-wasm", "wasm_example.js")) +assert os.path.exists(os.path.join("build", "release-wasm", "wasm_example.wasm")) diff --git a/examples/cross_build/wasm/bindings/conanfile.py b/examples/cross_build/wasm/bindings/conanfile.py index cf73bfbf..5daacbbb 100644 --- a/examples/cross_build/wasm/bindings/conanfile.py +++ b/examples/cross_build/wasm/bindings/conanfile.py @@ -9,20 +9,8 @@ class WasmExampleRecipe(ConanFile): name = "wasm-example" version = "1.0" package_type = "application" - - # Optional metadata - license = "" - author = " " - url = "" - description = "" - topics = ("", "", "") - - # Binary configuration settings = "os", "compiler", "build_type", "arch" - # Sources are located in the same place as this recipe, copy them to the recipe - exports_sources = "CMakeLists.txt", "src/*" - def layout(self): cmake_layout(self) @@ -33,13 +21,19 @@ def generate(self): deps = CMakeDeps(self) deps.generate() tc = CMakeToolchain(self) + + tc.extra_exelinkflags.append( + "-sEXPORTED_FUNCTIONS=['_malloc','_free'] \ + -sEXPORTED_RUNTIME_METHODS=['ccall','cwrap','getValue','setValue'] \ + -sENVIRONMENT=web \ + -sALLOW_MEMORY_GROWTH=1 \ + -sNO_EXIT_RUNTIME=1 \ + --shell-file ${CMAKE_SOURCE_DIR}/shell.html" + ) + tc.generate() def build(self): cmake = CMake(self) cmake.configure() cmake.build() - - def package(self): - cmake = CMake(self) - cmake.install() diff --git a/examples/cross_build/wasm/wasm64/ci_test_example.py b/examples/cross_build/wasm/wasm64/ci_test_example.py new file mode 100644 index 00000000..5840b4c9 --- /dev/null +++ b/examples/cross_build/wasm/wasm64/ci_test_example.py @@ -0,0 +1,17 @@ +import platform +from test.examples_tools import chdir, run + +run("conan build . --build=missing --profile:host ../profiles/wasm32") +run("conan build . --build=missing --profile:host ../profiles/wasm64") + +if platform.system() == "Windows": + with chdir("build"): + run("generators\\conanbuild.bat && node --version && node release-wasm\\wasm-alloc.js") + # Needs at least Node.js 24.0.0 + # run("generators\\conanbuild.bat && node --version && node release-wasm64\\wasm-alloc.js") +else: + with chdir("build/release-wasm"): + run(". generators/conanbuild.sh && node --version && node release-wasm/wasm-alloc.js") + # Needs at least Node.js 24.0.0 + # run(". generators/conanbuild.sh && node --version && node release-wasm64/wasm-alloc.js") + diff --git a/examples/cross_build/wasm/wasm_game/CMakeLists.txt b/examples/cross_build/wasm/wasm_game/CMakeLists.txt index 765a71f6..1d8682fc 100644 --- a/examples/cross_build/wasm/wasm_game/CMakeLists.txt +++ b/examples/cross_build/wasm/wasm_game/CMakeLists.txt @@ -9,5 +9,5 @@ target_link_libraries(wasm_game raylib) # Set the executable suffix to .html in order to generate a html page by # Emscripten (there is no way of setting this from a user toolchain or -# conanfile as it is later overriden by the emscripten toolchain) +# conanfile as it is later overridden by the Emscripten toolchain) set(CMAKE_EXECUTABLE_SUFFIX ".html") diff --git a/examples/cross_build/wasm/wasm_game/README.md b/examples/cross_build/wasm/wasm_game/README.md index 30ccccee..41d43e8f 100644 --- a/examples/cross_build/wasm/wasm_game/README.md +++ b/examples/cross_build/wasm/wasm_game/README.md @@ -4,8 +4,9 @@ This project is a copy of our [raylib](https://github.com/conan-io/examples2/tre It has minor modifications: -- C++ source code has been modified in order to accept mouse clicks as inputs as it is more convenient for a webpage -- `CMakeLists.txt` has been modified in order to link against raylib correctly using WASM +- C++ source code has been slightly modified in order to accept mouse clicks as inputs as it is more convenient for a webpage +- `CMakeLists.txt` has been modified in order to generate a `html` target which can bee opened by a web browser +- `conanfile.py` `generate()` method has been modified in order to link against raylib correctly using WASM - `-sUSE_GLFW=3 -sASYNCIFY`: see [raylib web manual](https://github.com/raysan5/raylib/wiki/Working-for-Web-(HTML5)#23-using-cmake) for a deeper explanation - `--shell-file`: generate the html code from the template diff --git a/examples/cross_build/wasm/wasm_game/ci_test_example.py b/examples/cross_build/wasm/wasm_game/ci_test_example.py new file mode 100644 index 00000000..18ead40a --- /dev/null +++ b/examples/cross_build/wasm/wasm_game/ci_test_example.py @@ -0,0 +1,8 @@ +import os +from test.examples_tools import run + +run("conan build . --build=missing --profile:host ../profiles/wasm32") + +assert os.path.exists(os.path.join("build", "release-wasm", "wasm_game.html")) +assert os.path.exists(os.path.join("build", "release-wasm", "wasm_game.js")) +assert os.path.exists(os.path.join("build", "release-wasm", "wasm_game.wasm")) From 899bb1df6b7b669d0c20b83c45fa5d5839396485 Mon Sep 17 00:00:00 2001 From: PerseoGI Date: Tue, 3 Jun 2025 12:03:28 +0200 Subject: [PATCH 06/11] Removed wasm64 compilation as it is not supported yet --- examples/cross_build/wasm/wasm64/ci_test_example.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/cross_build/wasm/wasm64/ci_test_example.py b/examples/cross_build/wasm/wasm64/ci_test_example.py index 5840b4c9..846a3430 100644 --- a/examples/cross_build/wasm/wasm64/ci_test_example.py +++ b/examples/cross_build/wasm/wasm64/ci_test_example.py @@ -2,7 +2,8 @@ from test.examples_tools import chdir, run run("conan build . --build=missing --profile:host ../profiles/wasm32") -run("conan build . --build=missing --profile:host ../profiles/wasm64") +# wasm64 not yet added to conan-io: https://github.com/conan-io/conan/pull/18400 +# run("conan build . --build=missing --profile:host ../profiles/wasm64") if platform.system() == "Windows": with chdir("build"): From 98d7b4f76a57d3be22032c91dce540c78955787f Mon Sep 17 00:00:00 2001 From: PerseoGI Date: Tue, 3 Jun 2025 12:24:18 +0200 Subject: [PATCH 07/11] Fixed issue on ci --- examples/cross_build/wasm/wasm64/ci_test_example.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/cross_build/wasm/wasm64/ci_test_example.py b/examples/cross_build/wasm/wasm64/ci_test_example.py index 846a3430..33fb2549 100644 --- a/examples/cross_build/wasm/wasm64/ci_test_example.py +++ b/examples/cross_build/wasm/wasm64/ci_test_example.py @@ -12,7 +12,9 @@ # run("generators\\conanbuild.bat && node --version && node release-wasm64\\wasm-alloc.js") else: with chdir("build/release-wasm"): - run(". generators/conanbuild.sh && node --version && node release-wasm/wasm-alloc.js") - # Needs at least Node.js 24.0.0 - # run(". generators/conanbuild.sh && node --version && node release-wasm64/wasm-alloc.js") + run(". generators/conanbuild.sh && node --version && node wasm-alloc.js") + + # Needs at least Node.js 24.0.0 + # with chdir("build/release-wasm64"): + # run(". generators/conanbuild.sh && node --version && node wasm-alloc.js") From 23e9dc6548fc369feff1349ce292125c4ea9b5b0 Mon Sep 17 00:00:00 2001 From: PerseoGI Date: Wed, 4 Jun 2025 10:50:47 +0200 Subject: [PATCH 08/11] Renamed and fixed profiles --- .../bindings/CMakeLists.txt | 4 +- .../{wasm => emscripten}/bindings/README.md | 17 +++++++- .../bindings/ci_test_example.py | 0 .../bindings/conanfile.py | 11 +++--- .../{wasm => emscripten}/bindings/main.cpp | 12 ++++-- .../{wasm => emscripten}/bindings/shell.html | 8 +++- .../cross_build/emscripten/profiles/asmjs | 8 ++++ examples/cross_build/emscripten/profiles/base | 39 +++++++++++++++++++ .../cross_build/emscripten/profiles/wasm32 | 8 ++++ .../cross_build/emscripten/profiles/wasm64 | 10 +++++ .../wasm64/CMakeLists.txt | 0 .../{wasm => emscripten}/wasm64/README.md | 0 .../wasm64/ci_test_example.py | 0 .../{wasm => emscripten}/wasm64/conanfile.py | 0 .../{wasm => emscripten}/wasm64/main.cpp | 0 .../wasm_game/CMakeLists.txt | 0 .../{wasm => emscripten}/wasm_game/README.md | 0 .../wasm_game/ci_test_example.py | 0 .../wasm_game/conanfile.py | 0 .../{wasm => emscripten}/wasm_game/main.cpp | 0 .../{wasm => emscripten}/wasm_game/shell.html | 0 examples/cross_build/wasm/profiles/wasm32 | 26 ------------- examples/cross_build/wasm/profiles/wasm64 | 28 ------------- 23 files changed, 104 insertions(+), 67 deletions(-) rename examples/cross_build/{wasm => emscripten}/bindings/CMakeLists.txt (73%) rename examples/cross_build/{wasm => emscripten}/bindings/README.md (63%) rename examples/cross_build/{wasm => emscripten}/bindings/ci_test_example.py (100%) rename examples/cross_build/{wasm => emscripten}/bindings/conanfile.py (77%) rename examples/cross_build/{wasm => emscripten}/bindings/main.cpp (83%) rename examples/cross_build/{wasm => emscripten}/bindings/shell.html (96%) create mode 100644 examples/cross_build/emscripten/profiles/asmjs create mode 100644 examples/cross_build/emscripten/profiles/base create mode 100644 examples/cross_build/emscripten/profiles/wasm32 create mode 100644 examples/cross_build/emscripten/profiles/wasm64 rename examples/cross_build/{wasm => emscripten}/wasm64/CMakeLists.txt (100%) rename examples/cross_build/{wasm => emscripten}/wasm64/README.md (100%) rename examples/cross_build/{wasm => emscripten}/wasm64/ci_test_example.py (100%) rename examples/cross_build/{wasm => emscripten}/wasm64/conanfile.py (100%) rename examples/cross_build/{wasm => emscripten}/wasm64/main.cpp (100%) rename examples/cross_build/{wasm => emscripten}/wasm_game/CMakeLists.txt (100%) rename examples/cross_build/{wasm => emscripten}/wasm_game/README.md (100%) rename examples/cross_build/{wasm => emscripten}/wasm_game/ci_test_example.py (100%) rename examples/cross_build/{wasm => emscripten}/wasm_game/conanfile.py (100%) rename examples/cross_build/{wasm => emscripten}/wasm_game/main.cpp (100%) rename examples/cross_build/{wasm => emscripten}/wasm_game/shell.html (100%) delete mode 100644 examples/cross_build/wasm/profiles/wasm32 delete mode 100644 examples/cross_build/wasm/profiles/wasm64 diff --git a/examples/cross_build/wasm/bindings/CMakeLists.txt b/examples/cross_build/emscripten/bindings/CMakeLists.txt similarity index 73% rename from examples/cross_build/wasm/bindings/CMakeLists.txt rename to examples/cross_build/emscripten/bindings/CMakeLists.txt index f8d76faf..0be17f0f 100644 --- a/examples/cross_build/wasm/bindings/CMakeLists.txt +++ b/examples/cross_build/emscripten/bindings/CMakeLists.txt @@ -2,9 +2,11 @@ cmake_minimum_required(VERSION 3.15) project(wasm_example CXX) find_package(Eigen3 REQUIRED) +find_package(ZLIB REQUIRED) +find_package(fmt REQUIRED) add_executable(wasm_example main.cpp) -target_link_libraries(${PROJECT_NAME} PRIVATE Eigen3::Eigen) +target_link_libraries(${PROJECT_NAME} PRIVATE Eigen3::Eigen ZLIB::ZLIB fmt::fmt) # Set the executable suffix to .html in order to generate a html page by # Emscripten (there is no way of setting this from a user toolchain or diff --git a/examples/cross_build/wasm/bindings/README.md b/examples/cross_build/emscripten/bindings/README.md similarity index 63% rename from examples/cross_build/wasm/bindings/README.md rename to examples/cross_build/emscripten/bindings/README.md index 848ace87..1bc3febd 100644 --- a/examples/cross_build/wasm/bindings/README.md +++ b/examples/cross_build/emscripten/bindings/README.md @@ -1,6 +1,5 @@ # WASM project with bindings and conan dependency - ## Build and run To compile the project: @@ -12,7 +11,21 @@ $ conan build . -pr:h ../profiles/wasm32 --build=missing To open a WASM webpage locally, most of the browsers will complain due to security reasons as WASM must be loaded asynchronous The easiest way of opening the generated webpage (should be in `build/release-wasm/wasm_example.html`) is by running a local server. -This can be done via `emrun` command (needs to be downloaded): +This can be done via `emrun` command: + +`emrun` is packaged with `emskd` recipe so it should be available by activating build environment: + +**POSIX** +```sh +$ source build/release-wasm/generators/conanbuild.sh +``` + +**Windows** +```sh +$ build\release-wasm\generators\conanbuild.bat +``` + +By this time, `emrun`, `node`, and other JS/WASM tools should be available in the path: ```sh $ emrun --browser build/release-wasm/wasm_example.html diff --git a/examples/cross_build/wasm/bindings/ci_test_example.py b/examples/cross_build/emscripten/bindings/ci_test_example.py similarity index 100% rename from examples/cross_build/wasm/bindings/ci_test_example.py rename to examples/cross_build/emscripten/bindings/ci_test_example.py diff --git a/examples/cross_build/wasm/bindings/conanfile.py b/examples/cross_build/emscripten/bindings/conanfile.py similarity index 77% rename from examples/cross_build/wasm/bindings/conanfile.py rename to examples/cross_build/emscripten/bindings/conanfile.py index 5daacbbb..db0a405a 100644 --- a/examples/cross_build/wasm/bindings/conanfile.py +++ b/examples/cross_build/emscripten/bindings/conanfile.py @@ -1,8 +1,5 @@ -import os - from conan import ConanFile from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout -from conan.tools.files import copy class WasmExampleRecipe(ConanFile): @@ -16,21 +13,23 @@ def layout(self): def requirements(self): self.requires("eigen/3.4.0") + self.requires("zlib/1.3.1") + self.requires("fmt/11.1.4") def generate(self): deps = CMakeDeps(self) deps.generate() tc = CMakeToolchain(self) + # HEAPxx values need to be exported explicitly since Emscripten 4.0.7 + # https://github.com/emscripten-core/emscripten/blob/main/ChangeLog.md#407---041525 tc.extra_exelinkflags.append( "-sEXPORTED_FUNCTIONS=['_malloc','_free'] \ - -sEXPORTED_RUNTIME_METHODS=['ccall','cwrap','getValue','setValue'] \ - -sENVIRONMENT=web \ + -sEXPORTED_RUNTIME_METHODS=['ccall','cwrap','getValue','setValue','HEAPF32'] \ -sALLOW_MEMORY_GROWTH=1 \ -sNO_EXIT_RUNTIME=1 \ --shell-file ${CMAKE_SOURCE_DIR}/shell.html" ) - tc.generate() def build(self): diff --git a/examples/cross_build/wasm/bindings/main.cpp b/examples/cross_build/emscripten/bindings/main.cpp similarity index 83% rename from examples/cross_build/wasm/bindings/main.cpp rename to examples/cross_build/emscripten/bindings/main.cpp index f60f99e0..ea643d82 100644 --- a/examples/cross_build/wasm/bindings/main.cpp +++ b/examples/cross_build/emscripten/bindings/main.cpp @@ -1,8 +1,10 @@ #include #include #include +#include #include #include +#include #ifdef __cplusplus #define EXTERN extern "C" @@ -36,18 +38,22 @@ EXTERN EMSCRIPTEN_KEEPALIVE void addOne(int32_t *input, int32_t *output) { } EXTERN EMSCRIPTEN_KEEPALIVE float sumArray(const float *data, int32_t size) { - // print data input - std::cout << "Data input: "; + fmt::print("Data input: "); for (int i = 0; i < size; ++i) { - std::cout << data[i] << " "; + fmt::print("{} ", data[i]); } std::cout << std::endl; Eigen::Map vec(data, size); return vec.sum(); } +EXTERN EMSCRIPTEN_KEEPALIVE void getZlibVersion() { + fmt::print("Zlib version being used: {}\n", zlibVersion()); +} + int main() { std::cout << "Hello World!" << std::endl; auto data = new float[5]{1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; std::cout << sumArray(data, 5) << std::endl; + fmt::print(zlibVersion()); } diff --git a/examples/cross_build/wasm/bindings/shell.html b/examples/cross_build/emscripten/bindings/shell.html similarity index 96% rename from examples/cross_build/wasm/bindings/shell.html rename to examples/cross_build/emscripten/bindings/shell.html index 747675e2..40b53c26 100644 --- a/examples/cross_build/wasm/bindings/shell.html +++ b/examples/cross_build/emscripten/bindings/shell.html @@ -1,7 +1,7 @@ -

Conan C++ WebAssembly Example

+

Conan C++ Emscripten Example


Downloading...
@@ -14,6 +14,9 @@

Conan C++ WebAssembly Example


+ +
+ @@ -103,6 +106,9 @@

Conan C++ WebAssembly Example

["Hello from C++ WebAssembly!"], ); }; + const getZlibVersion = () => { + Module.ccall("getZlibVersion", null, [], []); + }; // Example of a simple invocation to fibonachi const fibExample = () => { diff --git a/examples/cross_build/emscripten/profiles/asmjs b/examples/cross_build/emscripten/profiles/asmjs new file mode 100644 index 00000000..0879f767 --- /dev/null +++ b/examples/cross_build/emscripten/profiles/asmjs @@ -0,0 +1,8 @@ +include(base) + +[settings] +arch=asm.js + +[conf] +tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=2GB', '-sINITIAL_MEMORY=64MB'] +tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=2GB', '-sINITIAL_MEMORY=64MB'] diff --git a/examples/cross_build/emscripten/profiles/base b/examples/cross_build/emscripten/profiles/base new file mode 100644 index 00000000..26d1e624 --- /dev/null +++ b/examples/cross_build/emscripten/profiles/base @@ -0,0 +1,39 @@ +# Note: this profile uses emsdk package from Conan Center Index +# To use a local emsdk installation could be done by: +# a) Define a platform_tool_requires ensuring CC, CXX, etc are defined correctly in PATH +# [platform_tool_requires] +# emsdk/ +# b) Define compiler_executables +# tools.build:compiler_executables={'c':'emcc', 'cpp':'em++'} +# c) Define buildenv +# [buildenv] +# CC= +# CXX= +# AR .. + +[settings] +build_type=Release +compiler=emcc +compiler.cppstd=17 +compiler.libcxx=libc++ +compiler.version=4.0.9 +os=Emscripten + +[tool_requires] +emsdk/4.0.9 +ninja/[*] + +[conf] +tools.build:exelinkflags=['-sALLOW_MEMORY_GROWTH=1'] +tools.build:sharedlinkflags=['-sALLOW_MEMORY_GROWTH=1'] + +# Set Ninja as default generator as it is faster and will sove issues on Windows +tools.cmake.cmaketoolchain:generator=Ninja + +# Verbosity to see emcc invocations +tools.build:verbosity=verbose +tools.compilation:verbosity=verbose + +# Distinguish between architectures +tools.cmake.cmake_layout:build_folder_vars=['settings.build_type', 'settings.arch'] + diff --git a/examples/cross_build/emscripten/profiles/wasm32 b/examples/cross_build/emscripten/profiles/wasm32 new file mode 100644 index 00000000..6d49d4ad --- /dev/null +++ b/examples/cross_build/emscripten/profiles/wasm32 @@ -0,0 +1,8 @@ +include(base) + +[settings] +arch=wasm + +[conf] +tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB'] +tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB'] diff --git a/examples/cross_build/emscripten/profiles/wasm64 b/examples/cross_build/emscripten/profiles/wasm64 new file mode 100644 index 00000000..3c9c7cf5 --- /dev/null +++ b/examples/cross_build/emscripten/profiles/wasm64 @@ -0,0 +1,10 @@ +include(base) + +[settings] +arch=wasm64 + +[conf] +# In this early stage of wasm64, ALLOW_MEMORY_GROWTH is not having effect. Also it may not be the most efficient solution. +# wasm64 for now needs to declare INITIAL_MEMORY as the maximum memory +tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB'] +tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB'] diff --git a/examples/cross_build/wasm/wasm64/CMakeLists.txt b/examples/cross_build/emscripten/wasm64/CMakeLists.txt similarity index 100% rename from examples/cross_build/wasm/wasm64/CMakeLists.txt rename to examples/cross_build/emscripten/wasm64/CMakeLists.txt diff --git a/examples/cross_build/wasm/wasm64/README.md b/examples/cross_build/emscripten/wasm64/README.md similarity index 100% rename from examples/cross_build/wasm/wasm64/README.md rename to examples/cross_build/emscripten/wasm64/README.md diff --git a/examples/cross_build/wasm/wasm64/ci_test_example.py b/examples/cross_build/emscripten/wasm64/ci_test_example.py similarity index 100% rename from examples/cross_build/wasm/wasm64/ci_test_example.py rename to examples/cross_build/emscripten/wasm64/ci_test_example.py diff --git a/examples/cross_build/wasm/wasm64/conanfile.py b/examples/cross_build/emscripten/wasm64/conanfile.py similarity index 100% rename from examples/cross_build/wasm/wasm64/conanfile.py rename to examples/cross_build/emscripten/wasm64/conanfile.py diff --git a/examples/cross_build/wasm/wasm64/main.cpp b/examples/cross_build/emscripten/wasm64/main.cpp similarity index 100% rename from examples/cross_build/wasm/wasm64/main.cpp rename to examples/cross_build/emscripten/wasm64/main.cpp diff --git a/examples/cross_build/wasm/wasm_game/CMakeLists.txt b/examples/cross_build/emscripten/wasm_game/CMakeLists.txt similarity index 100% rename from examples/cross_build/wasm/wasm_game/CMakeLists.txt rename to examples/cross_build/emscripten/wasm_game/CMakeLists.txt diff --git a/examples/cross_build/wasm/wasm_game/README.md b/examples/cross_build/emscripten/wasm_game/README.md similarity index 100% rename from examples/cross_build/wasm/wasm_game/README.md rename to examples/cross_build/emscripten/wasm_game/README.md diff --git a/examples/cross_build/wasm/wasm_game/ci_test_example.py b/examples/cross_build/emscripten/wasm_game/ci_test_example.py similarity index 100% rename from examples/cross_build/wasm/wasm_game/ci_test_example.py rename to examples/cross_build/emscripten/wasm_game/ci_test_example.py diff --git a/examples/cross_build/wasm/wasm_game/conanfile.py b/examples/cross_build/emscripten/wasm_game/conanfile.py similarity index 100% rename from examples/cross_build/wasm/wasm_game/conanfile.py rename to examples/cross_build/emscripten/wasm_game/conanfile.py diff --git a/examples/cross_build/wasm/wasm_game/main.cpp b/examples/cross_build/emscripten/wasm_game/main.cpp similarity index 100% rename from examples/cross_build/wasm/wasm_game/main.cpp rename to examples/cross_build/emscripten/wasm_game/main.cpp diff --git a/examples/cross_build/wasm/wasm_game/shell.html b/examples/cross_build/emscripten/wasm_game/shell.html similarity index 100% rename from examples/cross_build/wasm/wasm_game/shell.html rename to examples/cross_build/emscripten/wasm_game/shell.html diff --git a/examples/cross_build/wasm/profiles/wasm32 b/examples/cross_build/wasm/profiles/wasm32 deleted file mode 100644 index 6ef908d2..00000000 --- a/examples/cross_build/wasm/profiles/wasm32 +++ /dev/null @@ -1,26 +0,0 @@ -[settings] -arch=wasm -build_type=Release -compiler=apple-clang -compiler.cppstd=gnu17 -compiler.cstd=gnu11 -compiler.libcxx=libc++ -compiler.version=17 -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' ] - -# Uncomment the following line to use emcc and em++ system compilers instead of conan packaged ones -# tools.build:compiler_executables={'c':'emcc', 'cpp':'em++'} - -# Verbosity -tools.build:verbosity=verbose -tools.compilation:verbosity=verbose - -# Distinguish between wasm32 and wasm64 architecture -tools.cmake.cmake_layout:build_folder_vars=['settings.build_type', 'settings.arch'] diff --git a/examples/cross_build/wasm/profiles/wasm64 b/examples/cross_build/wasm/profiles/wasm64 deleted file mode 100644 index 44b406f5..00000000 --- a/examples/cross_build/wasm/profiles/wasm64 +++ /dev/null @@ -1,28 +0,0 @@ -[settings] -arch=wasm64 -build_type=Release -compiler=apple-clang -compiler.cppstd=gnu17 -compiler.cstd=gnu11 -compiler.libcxx=libc++ -compiler.version=17 -os=Emscripten - -[tool_requires] -emsdk/[*] - -[conf] -# In this early stage of wasm64, ALLOW_MEMORY_GROWTH is not having effect. Also it may not be the most efficient solution. -# wasm64 for now needs to declare INITIAL_MEMORY as the maximum memory -tools.build:exelinkflags=['-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB'] -tools.build:sharedlinkflags=['-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB'] - -# Uncomment the following line to use emcc and em++ system compilers instead of conan packaged ones -# tools.build:compiler_executables={'c':'emcc', 'cpp':'em++'} - -# General config -tools.build:verbosity=verbose -tools.compilation:verbosity=verbose - -# Distinguish between wasm32 and wasm64 architecture -tools.cmake.cmake_layout:build_folder_vars=['settings.build_type', 'settings.arch'] From 239b6dd77b3e6c2f21080e4d647ab2986d478adc Mon Sep 17 00:00:00 2001 From: PerseoGI Date: Thu, 12 Jun 2025 17:21:36 +0200 Subject: [PATCH 09/11] Updated profiles and raylib game with wasm support --- .../emscripten/bindings/conanfile.py | 5 + .../cross_build/emscripten/profiles/asmjs | 2 +- .../emscripten/profiles/{base => emsdk-base} | 21 +--- .../emscripten/profiles/emsdk-native | 15 +++ .../cross_build/emscripten/profiles/wasm32 | 4 +- .../cross_build/emscripten/profiles/wasm64 | 9 +- .../emscripten/wasm_game/CMakeLists.txt | 13 --- .../emscripten/wasm_game/README.md | 18 --- .../emscripten/wasm_game/ci_test_example.py | 8 -- .../emscripten/wasm_game/conanfile.py | 27 ----- .../cross_build/emscripten/wasm_game/main.cpp | 108 ------------------ .../raylib/introduction/CMakeLists.txt | 8 +- .../libraries/raylib/introduction/README.md | 17 ++- .../raylib/introduction/ci_test_example.py | 9 ++ .../raylib/introduction/conanfile.py | 21 +++- .../libraries/raylib/introduction/main.cpp | 8 +- .../raylib/introduction}/shell.html | 0 17 files changed, 90 insertions(+), 203 deletions(-) rename examples/cross_build/emscripten/profiles/{base => emsdk-base} (51%) create mode 100644 examples/cross_build/emscripten/profiles/emsdk-native delete mode 100644 examples/cross_build/emscripten/wasm_game/CMakeLists.txt delete mode 100644 examples/cross_build/emscripten/wasm_game/README.md delete mode 100644 examples/cross_build/emscripten/wasm_game/ci_test_example.py delete mode 100644 examples/cross_build/emscripten/wasm_game/conanfile.py delete mode 100644 examples/cross_build/emscripten/wasm_game/main.cpp rename examples/{cross_build/emscripten/wasm_game => libraries/raylib/introduction}/shell.html (100%) diff --git a/examples/cross_build/emscripten/bindings/conanfile.py b/examples/cross_build/emscripten/bindings/conanfile.py index db0a405a..2075dca7 100644 --- a/examples/cross_build/emscripten/bindings/conanfile.py +++ b/examples/cross_build/emscripten/bindings/conanfile.py @@ -1,5 +1,6 @@ from conan import ConanFile from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout +from conan.errors import ConanInvalidConfiguration class WasmExampleRecipe(ConanFile): @@ -16,6 +17,10 @@ def requirements(self): self.requires("zlib/1.3.1") self.requires("fmt/11.1.4") + def validate(self): + if self.settings.os != "Emscripten": + raise ConanInvalidConfiguration("This example is only supported on Emscripten.") + def generate(self): deps = CMakeDeps(self) deps.generate() diff --git a/examples/cross_build/emscripten/profiles/asmjs b/examples/cross_build/emscripten/profiles/asmjs index 0879f767..b587992f 100644 --- a/examples/cross_build/emscripten/profiles/asmjs +++ b/examples/cross_build/emscripten/profiles/asmjs @@ -1,4 +1,4 @@ -include(base) +include(./emsdk-base) [settings] arch=asm.js diff --git a/examples/cross_build/emscripten/profiles/base b/examples/cross_build/emscripten/profiles/emsdk-base similarity index 51% rename from examples/cross_build/emscripten/profiles/base rename to examples/cross_build/emscripten/profiles/emsdk-base index 26d1e624..0982d9f5 100644 --- a/examples/cross_build/emscripten/profiles/base +++ b/examples/cross_build/emscripten/profiles/emsdk-base @@ -1,31 +1,21 @@ # Note: this profile uses emsdk package from Conan Center Index -# To use a local emsdk installation could be done by: -# a) Define a platform_tool_requires ensuring CC, CXX, etc are defined correctly in PATH -# [platform_tool_requires] -# emsdk/ -# b) Define compiler_executables -# tools.build:compiler_executables={'c':'emcc', 'cpp':'em++'} -# c) Define buildenv -# [buildenv] -# CC= -# CXX= -# AR .. +# To use a local emsdk installation use -pr:h -pr:h emsdk-native [settings] build_type=Release compiler=emcc compiler.cppstd=17 compiler.libcxx=libc++ -compiler.version=4.0.9 +compiler.version=4.0.10 os=Emscripten [tool_requires] -emsdk/4.0.9 +emsdk/4.0.10 ninja/[*] [conf] -tools.build:exelinkflags=['-sALLOW_MEMORY_GROWTH=1'] -tools.build:sharedlinkflags=['-sALLOW_MEMORY_GROWTH=1'] +tools.build:exelinkflags+=['-sALLOW_MEMORY_GROWTH=1'] +tools.build:sharedlinkflags+=['-sALLOW_MEMORY_GROWTH=1'] # Set Ninja as default generator as it is faster and will sove issues on Windows tools.cmake.cmaketoolchain:generator=Ninja @@ -36,4 +26,3 @@ tools.compilation:verbosity=verbose # Distinguish between architectures tools.cmake.cmake_layout:build_folder_vars=['settings.build_type', 'settings.arch'] - diff --git a/examples/cross_build/emscripten/profiles/emsdk-native b/examples/cross_build/emscripten/profiles/emsdk-native new file mode 100644 index 00000000..9470c5bb --- /dev/null +++ b/examples/cross_build/emscripten/profiles/emsdk-native @@ -0,0 +1,15 @@ +include(./emsdk-base) + +[platform_tool_requires] +emsdk/4.0.10 + +[conf] +tools.build:compiler_executables={'c':'emcc', 'cpp':'em++'} + +[buildenv] +CC=emcc +CXX=em++ +AR=emar +NM=emnm +RANLIB=emranlib +STRIP=emstrip diff --git a/examples/cross_build/emscripten/profiles/wasm32 b/examples/cross_build/emscripten/profiles/wasm32 index 6d49d4ad..d3349757 100644 --- a/examples/cross_build/emscripten/profiles/wasm32 +++ b/examples/cross_build/emscripten/profiles/wasm32 @@ -1,4 +1,4 @@ -include(base) +include(./emsdk-base) [settings] arch=wasm @@ -6,3 +6,5 @@ arch=wasm [conf] tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB'] tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB'] + +#tools.build:exelinkflags+=['-sMIN_NODE_VERSION=230000'] diff --git a/examples/cross_build/emscripten/profiles/wasm64 b/examples/cross_build/emscripten/profiles/wasm64 index 3c9c7cf5..8923a65c 100644 --- a/examples/cross_build/emscripten/profiles/wasm64 +++ b/examples/cross_build/emscripten/profiles/wasm64 @@ -1,4 +1,4 @@ -include(base) +include(./emsdk-base) [settings] arch=wasm64 @@ -6,5 +6,8 @@ arch=wasm64 [conf] # In this early stage of wasm64, ALLOW_MEMORY_GROWTH is not having effect. Also it may not be the most efficient solution. # wasm64 for now needs to declare INITIAL_MEMORY as the maximum memory -tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB'] -tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB'] +tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB', '-sASSERTIONS'] +tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB', '-sASSERTIONS'] + +#tools.build:exelinkflags+=['-sMIN_NODE_VERSION=221600'] +#tools.build:sharedlinkflags+=['-sMIN_NODE_VERSION=221600'] diff --git a/examples/cross_build/emscripten/wasm_game/CMakeLists.txt b/examples/cross_build/emscripten/wasm_game/CMakeLists.txt deleted file mode 100644 index 1d8682fc..00000000 --- a/examples/cross_build/emscripten/wasm_game/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -cmake_minimum_required(VERSION 3.23) -project(wasm_game) - -set(CMAKE_CXX_STANDARD 17) -find_package(raylib) - -add_executable(wasm_game main.cpp) -target_link_libraries(wasm_game raylib) - -# Set the executable suffix to .html in order to generate a html page by -# Emscripten (there is no way of setting this from a user toolchain or -# conanfile as it is later overridden by the Emscripten toolchain) -set(CMAKE_EXECUTABLE_SUFFIX ".html") diff --git a/examples/cross_build/emscripten/wasm_game/README.md b/examples/cross_build/emscripten/wasm_game/README.md deleted file mode 100644 index 41d43e8f..00000000 --- a/examples/cross_build/emscripten/wasm_game/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# WASM simple game - -This project is a copy of our [raylib](https://github.com/conan-io/examples2/tree/main/examples/libraries/raylib/introduction) example project. - -It has minor modifications: - -- C++ source code has been slightly modified in order to accept mouse clicks as inputs as it is more convenient for a webpage -- `CMakeLists.txt` has been modified in order to generate a `html` target which can bee opened by a web browser -- `conanfile.py` `generate()` method has been modified in order to link against raylib correctly using WASM - - `-sUSE_GLFW=3 -sASYNCIFY`: see [raylib web manual](https://github.com/raysan5/raylib/wiki/Working-for-Web-(HTML5)#23-using-cmake) for a deeper explanation - - `--shell-file`: generate the html code from the template - -![image](https://github.com/user-attachments/assets/941b5922-edb6-400f-9d38-ba805fc8a3ab) - - -## Build and run - -See instructions in [bindings example](https://github.com/conan-io/examples2/tree/main/examples/cross_build/wasm/bindings) diff --git a/examples/cross_build/emscripten/wasm_game/ci_test_example.py b/examples/cross_build/emscripten/wasm_game/ci_test_example.py deleted file mode 100644 index 18ead40a..00000000 --- a/examples/cross_build/emscripten/wasm_game/ci_test_example.py +++ /dev/null @@ -1,8 +0,0 @@ -import os -from test.examples_tools import run - -run("conan build . --build=missing --profile:host ../profiles/wasm32") - -assert os.path.exists(os.path.join("build", "release-wasm", "wasm_game.html")) -assert os.path.exists(os.path.join("build", "release-wasm", "wasm_game.js")) -assert os.path.exists(os.path.join("build", "release-wasm", "wasm_game.wasm")) diff --git a/examples/cross_build/emscripten/wasm_game/conanfile.py b/examples/cross_build/emscripten/wasm_game/conanfile.py deleted file mode 100644 index b96ecf26..00000000 --- a/examples/cross_build/emscripten/wasm_game/conanfile.py +++ /dev/null @@ -1,27 +0,0 @@ -from conan import ConanFile -from conan.tools.cmake import CMake, cmake_layout, CMakeDeps, CMakeToolchain - -class ConanApplication(ConanFile): - package_type = "application" - settings = "os", "compiler", "build_type", "arch" - - def layout(self): - cmake_layout(self) - - def requirements(self): - self.requires("raylib/5.5") - - def generate(self): - deps = CMakeDeps(self) - deps.generate() - - tc = CMakeToolchain(self) - tc.extra_exelinkflags.append( - "-sALLOW_MEMORY_GROWTH=1 -sUSE_GLFW=3 -sASYNCIFY --shell-file=${CMAKE_SOURCE_DIR}/shell.html" - ) - tc.generate() - - def build(self): - cmake = CMake(self) - cmake.configure() - cmake.build() diff --git a/examples/cross_build/emscripten/wasm_game/main.cpp b/examples/cross_build/emscripten/wasm_game/main.cpp deleted file mode 100644 index c35af2b0..00000000 --- a/examples/cross_build/emscripten/wasm_game/main.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include "raylib.h" - -int main() { - // --- Initialization --- - const int screenW = 800; - const int screenH = 350; - InitWindow(screenW, screenH, "Jump to Survive!"); - - // --- Player Setup --- - Rectangle player = { 100, screenH - 80, 40, 60 }; - float vy = 0; - const float gravity = 1000.0f; - const float jumpImpulse = -450.0f; - - // --- Ground Definition --- - const int groundY = screenH - 20; - - // --- Obstacle Management --- - std::vector obstacles; - float spawnTimer = 0.0f; - float spawnInterval = 1.2f; - const float obstacleSpeed = 300.0f; - - const float minSpawnInterval = 0.8f; - const float maxSpawnInterval = 1.6f; - - const int minObsWidth = 40; - const int maxObsWidth = 120; - - // --- Game State Variables --- - int score = 0; - bool gameOver = false; - - SetTargetFPS(60); - - while (!WindowShouldClose()) { - float dt = GetFrameTime(); - - if (!gameOver) { - // Jump logic - if ((IsKeyPressed(KEY_SPACE) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) && player.y + player.height >= groundY) { - vy = jumpImpulse; - } - vy += gravity * dt; - player.y += vy * dt; - if (player.y + player.height > groundY) { - player.y = groundY - player.height; - vy = 0; - } - - // Spawn obstacles with random width & interval - spawnTimer += dt; - if (spawnTimer >= spawnInterval) { - spawnTimer = 0.0f; - // recalc next interval - spawnInterval = GetRandomValue(int(minSpawnInterval*100), int(maxSpawnInterval*100)) / 100.0f; - // random width - int w = GetRandomValue(minObsWidth, maxObsWidth); - obstacles.push_back({ float(screenW), float(groundY - 40), float(w), 40.0f }); - } - - // Move & collide obstacles - for (int i = 0; i < (int)obstacles.size(); i++) { - obstacles[i].x -= obstacleSpeed * dt; - if (CheckCollisionRecs(player, obstacles[i])) { - gameOver = true; - } - } - // Remove off-screen & score - if (!obstacles.empty() && obstacles.front().x + obstacles.front().width < 0) { - obstacles.erase(obstacles.begin()); - score++; - } - } - else { - if (IsKeyPressed(KEY_R) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { - // reset everything - player.y = screenH - 80; - vy = 0; - obstacles.clear(); - spawnTimer = 0.0f; - spawnInterval = 1.2f; - score = 0; - gameOver = false; - } - } - - // --- Drawing --- - BeginDrawing(); - ClearBackground(RAYWHITE); - - DrawRectangle(0, groundY, screenW, 20, DARKGRAY); - DrawRectangleRec(player, BLUE); - for (auto &obs : obstacles) DrawRectangleRec(obs, RED); - - DrawText(TextFormat("Score: %d", score), 10, 10, 20, BLACK); - - if (gameOver) { - DrawText("GAME OVER! Press R or left click to restart", 180, screenH/2 - 20, 20, MAROON); - } - - EndDrawing(); - } - - CloseWindow(); - return 0; -} diff --git a/examples/libraries/raylib/introduction/CMakeLists.txt b/examples/libraries/raylib/introduction/CMakeLists.txt index 665b9004..9e0b0b5c 100644 --- a/examples/libraries/raylib/introduction/CMakeLists.txt +++ b/examples/libraries/raylib/introduction/CMakeLists.txt @@ -1,8 +1,14 @@ cmake_minimum_required(VERSION 3.23) project(runner_game) -set(CMAKE_CXX_STANDARD 17) find_package(raylib) add_executable(runner_game main.cpp) target_link_libraries(runner_game raylib) + +if(EMSCRIPTEN) + # Set the executable suffix to .html in order to generate a html page by + # Emscripten (there is no way of setting this from a user toolchain or + # conanfile as it is later overridden by the Emscripten toolchain) + set(CMAKE_EXECUTABLE_SUFFIX ".html") +endif() diff --git a/examples/libraries/raylib/introduction/README.md b/examples/libraries/raylib/introduction/README.md index d823e07f..0951150c 100644 --- a/examples/libraries/raylib/introduction/README.md +++ b/examples/libraries/raylib/introduction/README.md @@ -1,3 +1,18 @@ # Example using raylib to create a game -Example for using [raylib](https://www.raylib.com/) to create a simple runner game. \ No newline at end of file +Example for using [raylib](https://www.raylib.com/) to create a simple runner game. + + +## Emscripten - WebAssembly - WASM - compilation + +- `CMakeLists.txt` will generate a `html` target which can bee opened by a web browser +- `conanfile.py` `generate()` will link against raylib correctly using WASM + - `-sUSE_GLFW=3 -sASYNCIFY`: see [raylib web manual](https://github.com/raysan5/raylib/wiki/Working-for-Web-(HTML5)#23-using-cmake) for a deeper explanation + - `--shell-file`: generate the html code from the template + +![image](https://github.com/user-attachments/assets/941b5922-edb6-400f-9d38-ba805fc8a3ab) + + +### Build and run + +See instructions in [bindings example](https://github.com/conan-io/examples2/tree/main/examples/cross_build/wasm/bindings) diff --git a/examples/libraries/raylib/introduction/ci_test_example.py b/examples/libraries/raylib/introduction/ci_test_example.py index 34504fff..1da845b6 100644 --- a/examples/libraries/raylib/introduction/ci_test_example.py +++ b/examples/libraries/raylib/introduction/ci_test_example.py @@ -1,5 +1,6 @@ import platform from test.examples_tools import run +import os print("raylib example") @@ -11,3 +12,11 @@ else: run("cmake --preset conan-release") run("cmake --build --preset conan-release") + + +# WASM tests +run("conan build . --build=missing --profile:host ../../../cross_build/emscripten/profiles/wasm32") + +assert os.path.exists(os.path.join("build", "release-wasm", "runner_game.html")) +assert os.path.exists(os.path.join("build", "release-wasm", "runner_game.js")) +assert os.path.exists(os.path.join("build", "release-wasm", "runner_game.wasm")) diff --git a/examples/libraries/raylib/introduction/conanfile.py b/examples/libraries/raylib/introduction/conanfile.py index 2b565b0e..12512a69 100644 --- a/examples/libraries/raylib/introduction/conanfile.py +++ b/examples/libraries/raylib/introduction/conanfile.py @@ -1,13 +1,30 @@ from conan import ConanFile -from conan.tools.cmake import cmake_layout, CMakeToolchain +from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout +from conan.tools.build import check_min_cppstd class ConanApplication(ConanFile): package_type = "application" settings = "os", "compiler", "build_type", "arch" - generators = "CMakeDeps", "CMakeToolchain" + generators = "CMakeDeps" def layout(self): cmake_layout(self) def requirements(self): self.requires("raylib/5.5") + + def validate(self): + check_min_cppstd(self, "17") + + def generate(self): + tc = CMakeToolchain(self) + if self.settings.os == "Emscripten": + tc.extra_exelinkflags.append( + "-sUSE_GLFW=3 -sASYNCIFY --shell-file=${CMAKE_SOURCE_DIR}/shell.html" + ) + tc.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() diff --git a/examples/libraries/raylib/introduction/main.cpp b/examples/libraries/raylib/introduction/main.cpp index 2cd56404..4bbe3167 100644 --- a/examples/libraries/raylib/introduction/main.cpp +++ b/examples/libraries/raylib/introduction/main.cpp @@ -1,5 +1,5 @@ -#include "raylib.h" #include +#include "raylib.h" int main() { // --- Initialization --- @@ -39,7 +39,7 @@ int main() { if (!gameOver) { // Jump logic - if (IsKeyPressed(KEY_SPACE) && player.y + player.height >= groundY) { + if ((IsKeyPressed(KEY_SPACE) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) && player.y + player.height >= groundY) { vy = jumpImpulse; } vy += gravity * dt; @@ -74,7 +74,7 @@ int main() { } } else { - if (IsKeyPressed(KEY_R)) { + if (IsKeyPressed(KEY_R) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { // reset everything player.y = screenH - 80; vy = 0; @@ -97,7 +97,7 @@ int main() { DrawText(TextFormat("Score: %d", score), 10, 10, 20, BLACK); if (gameOver) { - DrawText("GAME OVER! Press R to restart", 200, screenH/2 - 20, 20, MAROON); + DrawText("GAME OVER! Press R or left click to restart", 180, screenH/2 - 20, 20, MAROON); } EndDrawing(); diff --git a/examples/cross_build/emscripten/wasm_game/shell.html b/examples/libraries/raylib/introduction/shell.html similarity index 100% rename from examples/cross_build/emscripten/wasm_game/shell.html rename to examples/libraries/raylib/introduction/shell.html From fce069e7b583e22712bfb5cac68ac1ed4a06e8b5 Mon Sep 17 00:00:00 2001 From: PerseoGI Date: Thu, 12 Jun 2025 18:10:46 +0200 Subject: [PATCH 10/11] Removed wasm profiles and use conan-toolchains ones --- .github/workflows/ros-tests.yml | 13 +++------ .../emscripten/bindings/ci_test_example.py | 3 +- .../cross_build/emscripten/profiles/asmjs | 8 ------ .../emscripten/profiles/emsdk-base | 28 ------------------- .../emscripten/profiles/emsdk-native | 15 ---------- .../cross_build/emscripten/profiles/wasm32 | 10 ------- .../cross_build/emscripten/profiles/wasm64 | 13 --------- .../cross_build/emscripten/wasm64/README.md | 3 +- .../emscripten/wasm64/ci_test_example.py | 14 +++++----- .../emscripten/wasm64/conanfile.py | 3 ++ 10 files changed, 18 insertions(+), 92 deletions(-) delete mode 100644 examples/cross_build/emscripten/profiles/asmjs delete mode 100644 examples/cross_build/emscripten/profiles/emsdk-base delete mode 100644 examples/cross_build/emscripten/profiles/emsdk-native delete mode 100644 examples/cross_build/emscripten/profiles/wasm32 delete mode 100644 examples/cross_build/emscripten/profiles/wasm64 diff --git a/.github/workflows/ros-tests.yml b/.github/workflows/ros-tests.yml index 209c6563..15514e2f 100644 --- a/.github/workflows/ros-tests.yml +++ b/.github/workflows/ros-tests.yml @@ -18,11 +18,6 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 - - name: Update ROS signing key (per ROS migration guide) - run: | - sudo rm /usr/share/keyrings/ros2-latest-archive-keyring.gpg - sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros2-latest-archive-keyring.gpg - - name: Configure environment and install Conan release run: | apt-get update && apt-get install -y python3 python3-pip @@ -44,10 +39,10 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 - - name: Update ROS signing key (per ROS migration guide) - run: | - sudo rm /usr/share/keyrings/ros2-latest-archive-keyring.gpg - sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros2-latest-archive-keyring.gpg + # - name: Update ROS signing key (per ROS migration guide) + # run: | + # sudo rm /usr/share/keyrings/ros2-latest-archive-keyring.gpg + # sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros2-latest-archive-keyring.gpg - name: Configure environment and install Conan from develop2 branch run: | diff --git a/examples/cross_build/emscripten/bindings/ci_test_example.py b/examples/cross_build/emscripten/bindings/ci_test_example.py index bc30cbcd..7f6d9e37 100644 --- a/examples/cross_build/emscripten/bindings/ci_test_example.py +++ b/examples/cross_build/emscripten/bindings/ci_test_example.py @@ -1,7 +1,8 @@ import os from test.examples_tools import run -run("conan build . --build=missing --profile:host ../profiles/wasm32") +run('conan config install https://github.com/perseoGI/conan-toolchains.git -sf conan_config --args "-b pgi/new/emsdk"') +run("conan build . --build=missing --profile:host emsdk/wasm32") assert os.path.exists(os.path.join("build", "release-wasm", "wasm_example.html")) assert os.path.exists(os.path.join("build", "release-wasm", "wasm_example.js")) diff --git a/examples/cross_build/emscripten/profiles/asmjs b/examples/cross_build/emscripten/profiles/asmjs deleted file mode 100644 index b587992f..00000000 --- a/examples/cross_build/emscripten/profiles/asmjs +++ /dev/null @@ -1,8 +0,0 @@ -include(./emsdk-base) - -[settings] -arch=asm.js - -[conf] -tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=2GB', '-sINITIAL_MEMORY=64MB'] -tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=2GB', '-sINITIAL_MEMORY=64MB'] diff --git a/examples/cross_build/emscripten/profiles/emsdk-base b/examples/cross_build/emscripten/profiles/emsdk-base deleted file mode 100644 index 0982d9f5..00000000 --- a/examples/cross_build/emscripten/profiles/emsdk-base +++ /dev/null @@ -1,28 +0,0 @@ -# Note: this profile uses emsdk package from Conan Center Index -# To use a local emsdk installation use -pr:h -pr:h emsdk-native - -[settings] -build_type=Release -compiler=emcc -compiler.cppstd=17 -compiler.libcxx=libc++ -compiler.version=4.0.10 -os=Emscripten - -[tool_requires] -emsdk/4.0.10 -ninja/[*] - -[conf] -tools.build:exelinkflags+=['-sALLOW_MEMORY_GROWTH=1'] -tools.build:sharedlinkflags+=['-sALLOW_MEMORY_GROWTH=1'] - -# Set Ninja as default generator as it is faster and will sove issues on Windows -tools.cmake.cmaketoolchain:generator=Ninja - -# Verbosity to see emcc invocations -tools.build:verbosity=verbose -tools.compilation:verbosity=verbose - -# Distinguish between architectures -tools.cmake.cmake_layout:build_folder_vars=['settings.build_type', 'settings.arch'] diff --git a/examples/cross_build/emscripten/profiles/emsdk-native b/examples/cross_build/emscripten/profiles/emsdk-native deleted file mode 100644 index 9470c5bb..00000000 --- a/examples/cross_build/emscripten/profiles/emsdk-native +++ /dev/null @@ -1,15 +0,0 @@ -include(./emsdk-base) - -[platform_tool_requires] -emsdk/4.0.10 - -[conf] -tools.build:compiler_executables={'c':'emcc', 'cpp':'em++'} - -[buildenv] -CC=emcc -CXX=em++ -AR=emar -NM=emnm -RANLIB=emranlib -STRIP=emstrip diff --git a/examples/cross_build/emscripten/profiles/wasm32 b/examples/cross_build/emscripten/profiles/wasm32 deleted file mode 100644 index d3349757..00000000 --- a/examples/cross_build/emscripten/profiles/wasm32 +++ /dev/null @@ -1,10 +0,0 @@ -include(./emsdk-base) - -[settings] -arch=wasm - -[conf] -tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB'] -tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB'] - -#tools.build:exelinkflags+=['-sMIN_NODE_VERSION=230000'] diff --git a/examples/cross_build/emscripten/profiles/wasm64 b/examples/cross_build/emscripten/profiles/wasm64 deleted file mode 100644 index 8923a65c..00000000 --- a/examples/cross_build/emscripten/profiles/wasm64 +++ /dev/null @@ -1,13 +0,0 @@ -include(./emsdk-base) - -[settings] -arch=wasm64 - -[conf] -# In this early stage of wasm64, ALLOW_MEMORY_GROWTH is not having effect. Also it may not be the most efficient solution. -# wasm64 for now needs to declare INITIAL_MEMORY as the maximum memory -tools.build:exelinkflags+=['-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB', '-sASSERTIONS'] -tools.build:sharedlinkflags+=['-sMAXIMUM_MEMORY=16GB', '-sINITIAL_MEMORY=16GB', '-sASSERTIONS'] - -#tools.build:exelinkflags+=['-sMIN_NODE_VERSION=221600'] -#tools.build:sharedlinkflags+=['-sMIN_NODE_VERSION=221600'] diff --git a/examples/cross_build/emscripten/wasm64/README.md b/examples/cross_build/emscripten/wasm64/README.md index d7f3ee70..1a27c419 100644 --- a/examples/cross_build/emscripten/wasm64/README.md +++ b/examples/cross_build/emscripten/wasm64/README.md @@ -4,11 +4,12 @@ This basic example aims to show the differences between cross compiling a project with `arch=wasm` (which stands for `wasm32` bits) and `arch=wasm64` the newly introduced architecture which supports WebAssembly 64-bits. +To To compile the project in 32 bits follow this instructions: ```sh -$ conan build . -pr ../profiles/wasm32 +$ conan build . -pr emsdk/wasm32 $ node build/release-wasm/wasm-alloc.js Current allocated: 1 GiB diff --git a/examples/cross_build/emscripten/wasm64/ci_test_example.py b/examples/cross_build/emscripten/wasm64/ci_test_example.py index 33fb2549..5d944cfb 100644 --- a/examples/cross_build/emscripten/wasm64/ci_test_example.py +++ b/examples/cross_build/emscripten/wasm64/ci_test_example.py @@ -1,20 +1,20 @@ import platform from test.examples_tools import chdir, run -run("conan build . --build=missing --profile:host ../profiles/wasm32") -# wasm64 not yet added to conan-io: https://github.com/conan-io/conan/pull/18400 -# run("conan build . --build=missing --profile:host ../profiles/wasm64") +run('conan config install https://github.com/perseoGI/conan-toolchains.git -sf conan_config --args "-b pgi/new/emsdk"') +run("conan build . --build=missing --profile:host emsdk/wasm32") +run("conan build . --build=missing --profile:host emsdk/wasm64") if platform.system() == "Windows": with chdir("build"): - run("generators\\conanbuild.bat && node --version && node release-wasm\\wasm-alloc.js") + run("generators\\conanbuild.bat && node --version && node release-wasm\\wasm-alloc") # Needs at least Node.js 24.0.0 - # run("generators\\conanbuild.bat && node --version && node release-wasm64\\wasm-alloc.js") + # run("generators\\conanbuild.bat && node --version && node release-wasm64\\wasm-alloc") else: with chdir("build/release-wasm"): - run(". generators/conanbuild.sh && node --version && node wasm-alloc.js") + run(". generators/conanbuild.sh && node --version && node wasm-alloc") # Needs at least Node.js 24.0.0 # with chdir("build/release-wasm64"): - # run(". generators/conanbuild.sh && node --version && node wasm-alloc.js") + # run(". generators/conanbuild.sh && node --version && node wasm-alloc") diff --git a/examples/cross_build/emscripten/wasm64/conanfile.py b/examples/cross_build/emscripten/wasm64/conanfile.py index a7453498..fb47625d 100644 --- a/examples/cross_build/emscripten/wasm64/conanfile.py +++ b/examples/cross_build/emscripten/wasm64/conanfile.py @@ -11,6 +11,9 @@ class WasmAllocatorRecipe(ConanFile): def layout(self): cmake_layout(self) + def requirements(self): + self.requires("icu/74.2") + def generate(self): deps = CMakeDeps(self) deps.generate() From 599e8d066ac99066318978642870c1d375ba60e6 Mon Sep 17 00:00:00 2001 From: PerseoGI Date: Wed, 9 Jul 2025 10:36:23 +0200 Subject: [PATCH 11/11] Removed ICU dep --- examples/cross_build/emscripten/wasm64/conanfile.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/cross_build/emscripten/wasm64/conanfile.py b/examples/cross_build/emscripten/wasm64/conanfile.py index fb47625d..a7453498 100644 --- a/examples/cross_build/emscripten/wasm64/conanfile.py +++ b/examples/cross_build/emscripten/wasm64/conanfile.py @@ -11,9 +11,6 @@ class WasmAllocatorRecipe(ConanFile): def layout(self): cmake_layout(self) - def requirements(self): - self.requires("icu/74.2") - def generate(self): deps = CMakeDeps(self) deps.generate()