diff --git a/3rdParty/libmpq/CMakeLists.txt b/3rdParty/libmpq/CMakeLists.txt index 114f133e1..b28197b74 100644 --- a/3rdParty/libmpq/CMakeLists.txt +++ b/3rdParty/libmpq/CMakeLists.txt @@ -1,4 +1,6 @@ -find_package(ZLIB REQUIRED) +if(NOT TARGET ZLIB::ZLIB) + find_package(ZLIB REQUIRED) +endif() if(NOT TARGET BZip2::BZip2) find_package(BZip2 REQUIRED) diff --git a/CMake/Dependencies.cmake b/CMake/Dependencies.cmake index aa1e1c1b7..394ee6865 100644 --- a/CMake/Dependencies.cmake +++ b/CMake/Dependencies.cmake @@ -1,8 +1,13 @@ # Options that control whether to use system dependencies or build them from source, # and whether to link them statically. include(functions/dependency_options) +include(functions/emscripten_system_library) -if(USE_SDL1) +if(EMSCRIPTEN) + # We use `USE_PTHREADS=1` here to get a version of SDL2 that supports threads. + emscripten_system_library("SDL2" SDL2::SDL2 USE_SDL=2 USE_PTHREADS=1) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/3rdParty/SDL2/CMake") +elseif(USE_SDL1) find_package(SDL REQUIRED) include_directories(${SDL_INCLUDE_DIR}) else() @@ -52,21 +57,25 @@ macro(_find_SDL_image QUIET_OR_REQUIRED) endif() endmacro() -if(NOT DEFINED DEVILUTIONX_SYSTEM_SDL_IMAGE) - _find_SDL_image(QUIET) - if(SDL_image_FOUND) - message("-- Found SDL_image") +if(EMSCRIPTEN) + emscripten_system_library("SDL_image" SDL2::SDL2_image USE_SDL_IMAGE=2 "SDL2_IMAGE_FORMATS='[\"png\"]'") +else() + if(NOT DEFINED DEVILUTIONX_SYSTEM_SDL_IMAGE) + _find_SDL_image(QUIET) + if(SDL_image_FOUND) + message("-- Found SDL_image") + else() + message("-- Suitable system SDL_image package not found, will use SDL_image from source") + set(DEVILUTIONX_SYSTEM_SDL_IMAGE OFF) + endif() + endif() + dependency_options("SDL_image" DEVILUTIONX_SYSTEM_SDL_IMAGE ON DEVILUTIONX_STATIC_SDL_IMAGE) + if(DEVILUTIONX_SYSTEM_SDL_IMAGE) + _find_SDL_image(REQUIRED) else() - message("-- Suitable system SDL_image package not found, will use SDL_image from source") - set(DEVILUTIONX_SYSTEM_SDL_IMAGE OFF) + add_subdirectory(3rdParty/SDL_image) endif() endif() -dependency_options("SDL_image" DEVILUTIONX_SYSTEM_SDL_IMAGE ON DEVILUTIONX_STATIC_SDL_IMAGE) -if(DEVILUTIONX_SYSTEM_SDL_IMAGE) - _find_SDL_image(REQUIRED) -else() - add_subdirectory(3rdParty/SDL_image) -endif() if(NOT NOSOUND) dependency_options("SDL_audiolib" DEVILUTIONX_SYSTEM_SDL_AUDIOLIB OFF DEVILUTIONX_STATIC_SDL_AUDIOLIB) @@ -110,6 +119,10 @@ else() add_subdirectory(3rdParty/bzip2) endif() +if(EMSCRIPTEN) + emscripten_system_library("zlib" ZLIB::ZLIB USE_ZLIB=1) +endif() + add_subdirectory(3rdParty/libsmackerdec) if(WIN32) diff --git a/CMake/Platforms.cmake b/CMake/Platforms.cmake index 1d696d0ff..9db6ba0e4 100644 --- a/CMake/Platforms.cmake +++ b/CMake/Platforms.cmake @@ -58,3 +58,7 @@ endif() if(IOS) include(platforms/ios) endif() + +if(EMSCRIPTEN) + include(platforms/emscripten) +endif() diff --git a/CMake/functions/emscripten_system_library.cmake b/CMake/functions/emscripten_system_library.cmake new file mode 100644 index 000000000..161000ee1 --- /dev/null +++ b/CMake/functions/emscripten_system_library.cmake @@ -0,0 +1,17 @@ +# This function defines a target that points to an Emscripten system library. +# +# Arguments: +# LIB_NAME: a human-readable library name. +# TARGET_NAME: the library target name +# ...ARGN: Emscripten flags. +# +# Example: +# emscripten_system_library("SDL2_image" SDL2::SDL2_image USE_SDL_IMAGE=2 "SDL2_IMAGE_FORMATS='[\"png\"]'") +function(emscripten_system_library LIB_NAME TARGET_NAME) + add_library(${TARGET_NAME} INTERFACE IMPORTED GLOBAL) + foreach(arg ${ARGN}) + target_compile_options(${TARGET_NAME} INTERFACE "SHELL:-s ${arg}") + target_link_options(${TARGET_NAME} INTERFACE "SHELL:-s ${arg}") + endforeach() + message("-- 📚 ${LIB_NAME}: Emscripten system library via ${ARGN}") +endfunction() diff --git a/CMake/platforms/emscripten.cmake b/CMake/platforms/emscripten.cmake new file mode 100644 index 000000000..a5c312541 --- /dev/null +++ b/CMake/platforms/emscripten.cmake @@ -0,0 +1,10 @@ +set(BUILD_TESTING OFF) +set(DISABLE_ZERO_TIER ON) +set(DEVILUTIONX_SYSTEM_SDL_AUDIOLIB OFF) +set(DEVILUTIONX_SYSTEM_LIBSODIUM OFF) +set(DEVILUTIONX_SYSTEM_LIBFMT OFF) + +# Emscripten ports do have a bzip2 but it fails to link with this error: +# warning: _BZ2_bzDecompress may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library +# error: undefined symbol: BZ2_bzDecompressEnd (referenced by top-level compiled C/C++ code) +set(DEVILUTIONX_SYSTEM_BZIP2 OFF) diff --git a/docs/building.md b/docs/building.md index 5327c36ae..63402d919 100644 --- a/docs/building.md +++ b/docs/building.md @@ -353,6 +353,18 @@ You can do this by selecting the DevilutionX icon, then hold right mouse button select Icons -> Information in the top menu. +
Emscripten + +Emscripten port is a work in progress. It builds but does not do more than that currently. + +To build, install the [Emscripten SDK](https://emscripten.org/docs/getting_started/downloads.html), then run: + +~~~ bash +emcmake cmake -S. -Bbuild-em -DCMAKE_BUILD_TYPE=Release +cmake --build build-em -j $(getconf _NPROCESSORS_ONLN) +~~~ +
+
CMake build options ### General