- Fixed emscripten build

- Added .github/workflows/eepp-emscripten-build-check.yml
  - Mirrors Linux CI structure.
  - Uses Premake 5 beta6.
  - Pins Emscripten 4.0.1.
  - Caches EMSDK system libraries.
  - Builds with all available cores.

- Completed Premake 5 Emscripten support:
  - Native wasm32 platform.
  - Correct .html application targets.
  - Asset preloading restored from Premake 4.
  - SDL2 supplied through Emscripten instead of native -lSDL2.
  - Static archives emitted under libs/emscripten/wasm32/.
  - Unsupported shared-library projects excluded.

- Modernized projects/emscripten/make.sh.
This commit is contained in:
Martín Lucas Golini
2026-07-25 00:47:18 -03:00
parent 2601048a17
commit 9894231d04
5 changed files with 127 additions and 43 deletions

View File

@@ -0,0 +1,37 @@
name: Emscripten
on: [push, pull_request]
env:
EM_VERSION: 4.0.1
EM_CACHE_FOLDER: emsdk-cache
jobs:
Emscripten:
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
ref: ${{ github.ref }}
fetch-depth: 2
- name: Checkout submodules
run: |
git submodule update --init --recursive
- name: Install Premake
run: |
wget https://cdn.ensoft.dev/eepp-assets/premake-5.0.0-beta6-linux.tar.gz
tar xvzf premake-5.0.0-beta6-linux.tar.gz
- name: Cache Emscripten system libraries
uses: actions/cache@v5
with:
path: ${{ env.EM_CACHE_FOLDER }}
key: emscripten-${{ env.EM_VERSION }}-${{ runner.os }}
- name: Setup Emscripten
uses: emscripten-core/setup-emsdk@v15
with:
version: ${{ env.EM_VERSION }}
actions-cache-folder: ${{ env.EM_CACHE_FOLDER }}
- name: Build
run: |
projects/emscripten/make.sh config=release_wasm32

View File

@@ -445,6 +445,23 @@ function build_link_configuration( package_name, use_ee_icon )
incdirs { "include" }
local extension = "";
if os.istarget("emscripten") and package_name ~= "eepp" and package_name ~= "eepp-static" then
local without_assets = {
["eepp-empty-window"] = true,
["eepp-sound"] = true,
["eepp-vbo-fbo-batch"] = true,
["eepp-physics-demo"] = true,
["eepp-http-request"] = true,
}
if not without_assets[package_name] then
if package_name == "ecode" then
linkoptions { "--preload-file " .. package_name .. "/assets/" }
else
linkoptions { "--preload-file assets/" }
end
end
end
if package_name == "eepp" then
defines { "EE_EXPORTS" }
elseif package_name == "eepp-static" then
@@ -583,6 +600,9 @@ function build_link_configuration( package_name, use_ee_icon )
filter "system:emscripten"
targetname ( package_name .. extension )
if package_name ~= "eepp" and package_name ~= "eepp-static" then
targetextension ".html"
end
linkoptions { "-O3 -s TOTAL_MEMORY=536870912 -s ALLOW_MEMORY_GROWTH=1 -s USE_SDL=2" }
buildoptions { "-O3 -s USE_SDL=2 -s PRECISE_F32=1 -s ENVIRONMENT=worker,web" }
buildoptions { "-s USE_PTHREADS=1" }
@@ -739,7 +759,9 @@ end
function add_sdl2()
print("Using SDL2 backend");
if not can_add_static_backend("SDL2") then
table.insert( link_list, get_backend_link_name( "SDL2" ) )
if not os.istarget("emscripten") then
table.insert( link_list, get_backend_link_name( "SDL2" ) )
end
else
print("Using static backend")
insert_static_backend( "SDL2" )
@@ -1042,6 +1064,8 @@ function build_eepp( build_name )
end
function target_dir_lib(path)
filter "architecture:wasm32"
targetdir("libs/" .. os.target() .. "/wasm32/" .. path .. "/")
filter "architecture:x86"
targetdir("libs/" .. os.target() .. "/x86/" .. path .. "/")
filter "architecture:x86_64"
@@ -1084,6 +1108,9 @@ workspace "eepp"
if _ACTION == "ninja" then
configurations { "debug", "release" }
platforms { get_architecture() }
elseif os.istarget("emscripten") then
configurations { "debug", "release" }
platforms { "wasm32" }
else
configurations { "debug", "release" }
platforms { "x86_64", "x86", "arm64" }
@@ -1111,6 +1138,9 @@ workspace "eepp"
filter "platforms:x86_64"
architecture "x86_64"
filter "platforms:wasm32"
architecture "wasm32"
filter { "platforms:x86_64", "system:macosx" }
architecture "x86_64"
buildoptions { "-arch x86_64" }
@@ -1518,19 +1548,21 @@ workspace "eepp"
filter "action:not vs*"
buildoptions { "-Wall" }
project "eepp-maps"
kind "SharedLib"
language "C++"
cppdialect "C++20"
incdirs { "include", "src/modules/maps/include/","src/modules/maps/src/" }
files { "src/modules/maps/src/**.cpp" }
links { "eepp-shared" }
defines { "EE_MAPS_EXPORTS" }
build_base_cpp_configuration( "eepp-maps" )
postsymlinklib_arch( "eepp-maps" )
target_dir_lib("")
filter "action:not vs*"
buildoptions { "-Wall" }
if not os.istarget("emscripten") then
project "eepp-maps"
kind "SharedLib"
language "C++"
cppdialect "C++20"
incdirs { "include", "src/modules/maps/include/","src/modules/maps/src/" }
files { "src/modules/maps/src/**.cpp" }
links { "eepp-shared" }
defines { "EE_MAPS_EXPORTS" }
build_base_cpp_configuration( "eepp-maps" )
postsymlinklib_arch( "eepp-maps" )
target_dir_lib("")
filter "action:not vs*"
buildoptions { "-Wall" }
end
project "eepp-physics-static"
kind "StaticLib"
@@ -1547,19 +1579,21 @@ workspace "eepp"
filter "action:not vs*"
buildoptions { "-Wall" }
project "eepp-physics"
kind "SharedLib"
language "C++"
cppdialect "C++20"
incdirs { "include", "src/modules/physics/include/","src/modules/physics/src/" }
files { "src/modules/physics/src/**.cpp", "src/eepp/physics/constraints/*.cpp" }
links { "chipmunk-static", "eepp-shared" }
defines { "EE_PHYSICS_EXPORTS" }
build_base_cpp_configuration( "eepp-physics" )
postsymlinklib_arch( "eepp-physics" )
target_dir_lib("")
filter "action:not vs*"
buildoptions { "-Wall" }
if not os.istarget("emscripten") then
project "eepp-physics"
kind "SharedLib"
language "C++"
cppdialect "C++20"
incdirs { "include", "src/modules/physics/include/","src/modules/physics/src/" }
files { "src/modules/physics/src/**.cpp", "src/eepp/physics/constraints/*.cpp" }
links { "chipmunk-static", "eepp-shared" }
defines { "EE_PHYSICS_EXPORTS" }
build_base_cpp_configuration( "eepp-physics" )
postsymlinklib_arch( "eepp-physics" )
target_dir_lib("")
filter "action:not vs*"
buildoptions { "-Wall" }
end
project "eterm-static"
kind "StaticLib"
@@ -1605,12 +1639,14 @@ workspace "eepp"
target_dir_lib("")
end
project "eepp-shared"
kind "SharedLib"
language "C++"
build_eepp( "eepp" )
postsymlinklib_arch( "eepp" )
target_dir_lib("")
if not os.istarget("emscripten") then
project "eepp-shared"
kind "SharedLib"
language "C++"
build_eepp( "eepp" )
postsymlinklib_arch( "eepp" )
target_dir_lib("")
end
-- Examples
project "eepp-external-shader"

View File

@@ -1,17 +1,25 @@
#!/bin/sh
# Currently latest emsdk tested and working version: latest-fastcomp
# remember to first set the environment
set -e
# Currently tested emsdk version: 4.0.1
# Remember to first set the environment:
# source /path/to/emsdk/emsdk_env.sh
cd $(dirname "$0") || exit
cd "$(dirname "$0")"
unset CPLUS_INCLUDE_PATH
premake4 --file=../../premake4.lua --with-gles2 --with-static-eepp --platform=emscripten --with-backend=SDL2 gmake
cd ../../make/emscripten/ || exit
PREMAKE5=${PREMAKE5:-premake5}
if [ -x ../../premake5 ]; then
PREMAKE5=../../premake5
fi
"$PREMAKE5" --file=../../premake5.lua --os=emscripten --with-gles2 --with-static-eepp --with-backend=SDL2 gmake
cd ../../make/emscripten/
rm -rf ./assets
cp -r ../../bin/assets/ .
rm assets/fonts/NotoColorEmoji.ttf assets/fonts/DejaVuSansMonoNerdFontComplete.ttf assets/fonts/DroidSansFallbackFull.ttf
rm -f assets/fonts/NotoColorEmoji.ttf assets/fonts/DejaVuSansMonoNerdFontComplete.ttf assets/fonts/DroidSansFallbackFull.ttf
rm -rf ./ecode
mkdir ecode
cp -r ../../bin/assets/ ecode/assets/
rm ecode/assets/fonts/DejaVuSansMonoNerdFontComplete.ttf ecode/assets/fonts/DroidSansFallbackFull.ttf ecode/assets/fonts/NotoColorEmoji.ttf ecode/assets/test.zip ecode/assets/ca-bundle.pem ecode/assets/icon/ee.icns ecode/assets/icon/ee.rc ecode/assets/icon/ee.res ecode/assets/icon/ee.ico ecode/assets/fonts/*.png ecode/assets/fonts/*.fnt ecode/assets/fonts/OpenSans-Regular.ttf ecode/assets/icon/ecode.icns ecode/assets/icon/eterm* ecode/assets/icon/*.svg
rm -r ecode/assets/atlases ecode/assets/screenshots ecode/assets/cursors ecode/assets/layouts ecode/assets/maps ecode/assets/sounds ecode/assets/sprites ecode/assets/tiles ecode/assets/shaders ecode/assets/ui/uitheme*
rm -f ecode/assets/fonts/DejaVuSansMonoNerdFontComplete.ttf ecode/assets/fonts/DroidSansFallbackFull.ttf ecode/assets/fonts/NotoColorEmoji.ttf ecode/assets/test.zip ecode/assets/ca-bundle.pem ecode/assets/icon/ee.icns ecode/assets/icon/ee.rc ecode/assets/icon/ee.res ecode/assets/icon/ee.ico ecode/assets/fonts/*.png ecode/assets/fonts/*.fnt ecode/assets/fonts/OpenSans-Regular.ttf ecode/assets/icon/ecode.icns ecode/assets/icon/eterm* ecode/assets/icon/*.svg
rm -rf ecode/assets/atlases ecode/assets/screenshots ecode/assets/cursors ecode/assets/layouts ecode/assets/maps ecode/assets/sounds ecode/assets/sprites ecode/assets/tiles ecode/assets/shaders ecode/assets/ui/uitheme*
emmake make -j"$(nproc)" "$@"

View File

@@ -2257,7 +2257,9 @@ static bool _isOSUsingDarkColorScheme() {
#elif EE_PLATFORM == EE_PLATFORM_EMSCRIPTEN
// Executes JavaScript: window.matchMedia('(prefers-color-scheme: dark)').matches
return EM_ASM_INT( {
if ( typeof window != = 'undefined' && window.matchMedia ) {
// EM_ASM stringifies C/C++ preprocessing tokens. JavaScript's !== is split into
// "!= =" and becomes invalid, so use != for this typeof string comparison.
if ( typeof window != 'undefined' && window.matchMedia ) {
return window.matchMedia( '(prefers-color-scheme: dark)' ).matches ? 1 : 0;
}
return 0;

View File

@@ -1420,7 +1420,8 @@ void EETest::loadTextures() {
tImg.createMaskFromColor( ColorA( 0, 0, 0, 255 ), 0 );
Tiles[7] = SG->add( TF->loadFromPixels( tImg.getPixelsPtr(), tImg.getWidth(),
tImg.getHeight(), tImg.getChannels() ),
"8" );
"8" )
.get();
#else
Tiles[7] = SG->add( TF->loadFromFile( MyPath + "sprites/objects/2.png" ), "8" ).get();
Tiles[7]->getTexture()->createMaskFromColor( Color( 0, 0, 0, 255 ), 0 );