changeset 1549:a48ae10857b1

packaging of the WebAssembly module
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 13 Aug 2020 15:56:01 +0200
parents 65eccce95882
children 012ab2c1f23b
files Applications/Samples/WebAssembly/CMakeLists.txt Applications/StoneWebViewer/WebAssembly/CMakeLists.txt Applications/StoneWebViewer/WebAssembly/StoneModule/CMakeLists.txt Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake OrthancStone/Resources/Orthanc/CMake/EmscriptenParameters.cmake OrthancStone/Resources/SyncOrthancFolder.py OrthancStone/SharedLibrary/OrthancStone.h.in OrthancStone/SharedLibrary/WebAssembly/CMakeLists.txt OrthancStone/Sources/Oracle/WebAssemblyOracle.cpp OrthancStone/Sources/Oracle/WebAssemblyOracle_Includes.h OrthancStone/Sources/Viewport/WebAssemblyViewport.cpp OrthancStone/Sources/Viewport/WebAssemblyViewport.h
diffstat 13 files changed, 550 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/Samples/WebAssembly/CMakeLists.txt	Thu Aug 13 09:57:35 2020 +0200
+++ b/Applications/Samples/WebAssembly/CMakeLists.txt	Thu Aug 13 15:56:01 2020 +0200
@@ -16,18 +16,16 @@
   set(WASM_FLAGS "${WASM_FLAGS} -s SAFE_HEAP=1")
 endif()
 
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WASM_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WASM_FLAGS}")
-
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ERROR_ON_UNDEFINED_SYMBOLS=1")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ASSERTIONS=1 -s DISABLE_EXCEPTION_CATCHING=0")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_MEMORY=268435456")  # 256MB + resize
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1")
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'")
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s ERROR_ON_UNDEFINED_SYMBOLS=1")
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s ASSERTIONS=1 -s DISABLE_EXCEPTION_CATCHING=0")
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_MEMORY=268435456")  # 256MB + resize
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1")
 add_definitions(
   -DDISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1
 )
 
+
 # Stone of Orthanc configuration
 # ---------------------------------------------------------------
 set(ALLOW_DOWNLOADS ON)
@@ -78,6 +76,12 @@
   ../Common/RtViewerView.h
   )
 
+set_target_properties(RtViewerWasm
+  PROPERTIES
+  COMPILE_FLAGS "${WASM_FLAGS}"
+  LINK_FLAGS "${WASM_LINKER_FLAGS}"
+  )
+
 target_link_libraries(RtViewerWasm OrthancStone)
 
 # Declare installation files for the module
@@ -112,6 +116,12 @@
   SingleFrameViewer/SingleFrameViewer.cpp
   )
 
+set_target_properties(SingleFrameViewerWasm
+  PROPERTIES
+  COMPILE_FLAGS "${WASM_FLAGS}"
+  LINK_FLAGS "${WASM_LINKER_FLAGS}"
+  )
+
 target_link_libraries(SingleFrameViewerWasm OrthancStone)
 
 # Declare installation files for the module
--- a/Applications/StoneWebViewer/WebAssembly/CMakeLists.txt	Thu Aug 13 09:57:35 2020 +0200
+++ b/Applications/StoneWebViewer/WebAssembly/CMakeLists.txt	Thu Aug 13 15:56:01 2020 +0200
@@ -11,23 +11,21 @@
 
 set(EMSCRIPTEN_SET_LLVM_WASM_BACKEND ON CACHE BOOL "")
 
-set(WASM_FLAGS "-s WASM=1 -s FETCH=1")
+set(WASM_FLAGS "${WASM_FLAGS} -s WASM=1 -s FETCH=1")
 if (CMAKE_BUILD_TYPE STREQUAL "Debug")
   set(WASM_FLAGS "${WASM_FLAGS} -s SAFE_HEAP=1")
 endif()
 
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WASM_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WASM_FLAGS}")
-
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ERROR_ON_UNDEFINED_SYMBOLS=1")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ASSERTIONS=1 -s DISABLE_EXCEPTION_CATCHING=0")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_MEMORY=268435456")  # 256MB + resize
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1")
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'")
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s ERROR_ON_UNDEFINED_SYMBOLS=1")
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s ASSERTIONS=1 -s DISABLE_EXCEPTION_CATCHING=0")
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_MEMORY=268435456")  # 256MB + resize
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1")
 add_definitions(
   -DDISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1
 )
 
+
 # Stone of Orthanc configuration
 # ---------------------------------------------------------------
 set(ALLOW_DOWNLOADS ON)
@@ -46,6 +44,10 @@
 # populate the ORTHANC_STONE_SOURCES CMake variable
 include(${ORTHANC_STONE_ROOT}/Resources/CMake/OrthancStoneConfiguration.cmake)
 
+include_directories(
+  ${CMAKE_SOURCE_DIR}/../../../OrthancStone/Sources/
+  )
+
 if (CMAKE_BUILD_TYPE MATCHES Debug)
   # specific flags go here
 elseif (CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
@@ -58,8 +60,6 @@
 
 ################################################################################
 
-project(StoneWebViewer)
-
 
 # Create the wrapper to call C++ from JavaScript
 # ---------------------------------------------------------------
@@ -92,6 +92,12 @@
   StoneWebViewer.cpp
   )
 
+set_target_properties(StoneWebViewer
+  PROPERTIES
+  COMPILE_FLAGS "${WASM_FLAGS}"
+  LINK_FLAGS "${WASM_LINKER_FLAGS}"
+  )
+
 # Make sure to have the wrapper generated
 add_dependencies(StoneWebViewer StoneWrapper)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Applications/StoneWebViewer/WebAssembly/StoneModule/CMakeLists.txt	Thu Aug 13 15:56:01 2020 +0200
@@ -0,0 +1,142 @@
+cmake_minimum_required(VERSION 2.8.3)
+
+project(OrthancStone)
+
+set(ORTHANC_STONE_MODULE_PREFIX "${CMAKE_SOURCE_DIR}/../../../../wasm-binaries/OrthancStoneModule" CACHE PATH "Where to find the precompiled WebAssembly module of Orthanc Stone")
+set(ORTHANC_STONE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/../../../../wasm-binaries/StoneWebViewer" CACHE PATH "Where to put the WebAssembly binaries")
+set(EMSCRIPTEN_TARGET_MODE "wasm" CACHE STRING "Sets the target mode for Emscripten (can be \"wasm\" or \"asm.js\")")
+mark_as_advanced(EMSCRIPTEN_TARGET_MODE)
+
+
+set(WASM_FLAGS "-s MAIN_MODULE=1")  # Must be before "Compiler.cmake"
+
+# https://github.com/emscripten-core/emscripten/issues/11407
+set(WASM_FLAGS "${WASM_FLAGS} -s DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[\"_emscripten_fetch_xhr\",\"_emscripten_fetch_load_cached_data\",\"_emscripten_fetch_delete_cached_data\",\"_emscripten_fetch_cache_data\"]")
+
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s RUNTIME_LINKED_LIBS='[\"OrthancStoneModule.wasm\"]'")
+
+
+
+# Configuration of the Emscripten compiler for WebAssembly target
+# ---------------------------------------------------------------
+set(USE_WASM ON CACHE BOOL "")
+
+set(EMSCRIPTEN_SET_LLVM_WASM_BACKEND ON CACHE BOOL "")
+
+set(WASM_FLAGS "${WASM_FLAGS} -s WASM=1 -s FETCH=1")
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+  set(WASM_FLAGS "${WASM_FLAGS} -s SAFE_HEAP=1")
+endif()
+
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'")
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s ERROR_ON_UNDEFINED_SYMBOLS=1")
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s ASSERTIONS=1 -s DISABLE_EXCEPTION_CATCHING=0")
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_MEMORY=268435456")  # 256MB + resize
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1")
+add_definitions(
+  -DDISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1
+)
+
+
+
+# Stone of Orthanc configuration, to be used as module
+# ---------------------------------------------------------------
+
+
+include(${CMAKE_SOURCE_DIR}/../../../../OrthancStone/Resources/Orthanc/CMake/Compiler.cmake)
+
+add_definitions(
+  -DORTHANC_STONE_MAX_TAG_LENGTH=256  # TODO => share with OrthancStone
+  )
+
+include_directories(
+  ${ORTHANC_STONE_MODULE_PREFIX}/include
+  ${ORTHANC_STONE_MODULE_PREFIX}/include/orthanc-framework
+  ${ORTHANC_STONE_MODULE_PREFIX}/include/orthanc-stone
+  )
+
+
+
+################################################################################
+
+
+# Create the wrapper to call C++ from JavaScript
+# ---------------------------------------------------------------
+
+set(LIBCLANG "libclang-4.0.so.1" CACHE PATH "Version of clang to generate the code model")
+set(STONE_WRAPPER ${CMAKE_CURRENT_BINARY_DIR}/stone.js)
+
+add_custom_command(
+  COMMAND
+  ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/../ParseWebAssemblyExports.py --libclang=${LIBCLANG} ${CMAKE_SOURCE_DIR}/../StoneWebViewer.cpp > ${STONE_WRAPPER}
+  DEPENDS
+  ${CMAKE_SOURCE_DIR}/../StoneWebViewer.cpp
+  ${CMAKE_SOURCE_DIR}/../ParseWebAssemblyExports.py
+  OUTPUT
+  ${STONE_WRAPPER}
+  )
+
+add_custom_target(StoneWrapper
+  DEPENDS
+  ${STONE_WRAPPER}
+  )  
+
+
+# Define the WASM module
+# ---------------------------------------------------------------
+
+aux_source_directory(
+  ${ORTHANC_STONE_MODULE_PREFIX}/src/orthanc-stone/
+  ORTHANC_STONE_SOURCES)
+
+add_executable(StoneWebViewer
+  ${AUTOGENERATED_SOURCES}
+  ${ORTHANC_STONE_SOURCES}
+  ../StoneWebViewer.cpp
+  )
+
+set_target_properties(StoneWebViewer
+  PROPERTIES
+  COMPILE_FLAGS "${WASM_FLAGS}"
+  LINK_FLAGS "${WASM_LINKER_FLAGS}"
+  )
+
+# Make sure to have the wrapper generated
+add_dependencies(StoneWebViewer StoneWrapper)
+
+
+# Declare installation files for the module
+# ---------------------------------------------------------------
+
+install(
+  TARGETS StoneWebViewer
+  RUNTIME DESTINATION ${ORTHANC_STONE_INSTALL_PREFIX}
+  )
+
+
+# Declare installation files for the companion files (web scaffolding)
+# please note that ${CMAKE_CURRENT_BINARY_DIR}/StoneWebViewer.js
+# (the generated JS loader for the WASM module) is handled by the `install`
+# section above: it is considered to be the binary output of 
+# the linker.
+# ---------------------------------------------------------------
+install(
+  FILES
+  ${CMAKE_CURRENT_BINARY_DIR}/StoneWebViewer.wasm
+  ${CMAKE_SOURCE_DIR}/../../WebApplication/app.css
+  ${CMAKE_SOURCE_DIR}/../../WebApplication/app.js
+  ${CMAKE_SOURCE_DIR}/../../WebApplication/index.html
+  ${ORTHANC_STONE_MODULE_PREFIX}/lib/OrthancStoneModule.wasm  # NEW
+  ${STONE_WRAPPER}
+  DESTINATION ${ORTHANC_STONE_INSTALL_PREFIX}
+  )
+
+install(
+  FILES
+  ${CMAKE_SOURCE_DIR}/../../WebApplication/img/grid1x1.png
+  ${CMAKE_SOURCE_DIR}/../../WebApplication/img/grid1x2.png
+  ${CMAKE_SOURCE_DIR}/../../WebApplication/img/grid2x1.png
+  ${CMAKE_SOURCE_DIR}/../../WebApplication/img/grid2x2.png
+  ${CMAKE_SOURCE_DIR}/../../WebApplication/img/loading.gif
+  DESTINATION ${ORTHANC_STONE_INSTALL_PREFIX}/img
+  )
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp	Thu Aug 13 09:57:35 2020 +0200
+++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp	Thu Aug 13 15:56:01 2020 +0200
@@ -53,28 +53,32 @@
   }
 
 
+// Orthanc framework includes
 #include <Cache/MemoryObjectCache.h>
 #include <DicomFormat/DicomArray.h>
 #include <DicomParsing/Internals/DicomImageDecoder.h>
+#include <DicomParsing/ParsedDicomFile.h>
 #include <Images/Image.h>
 #include <Images/ImageProcessing.h>
 #include <Images/JpegReader.h>
 #include <Logging.h>
 
-#include "../../../OrthancStone/Sources/Loaders/DicomResourcesLoader.h"
-#include "../../../OrthancStone/Sources/Loaders/SeriesMetadataLoader.h"
-#include "../../../OrthancStone/Sources/Loaders/SeriesThumbnailsLoader.h"
-#include "../../../OrthancStone/Sources/Loaders/WebAssemblyLoadersContext.h"
-#include "../../../OrthancStone/Sources/Messages/ObserverBase.h"
-#include "../../../OrthancStone/Sources/Oracle/ParseDicomFromWadoCommand.h"
-#include "../../../OrthancStone/Sources/Scene2D/ColorTextureSceneLayer.h"
-#include "../../../OrthancStone/Sources/Scene2D/FloatTextureSceneLayer.h"
-#include "../../../OrthancStone/Sources/Scene2D/PolylineSceneLayer.h"
-#include "../../../OrthancStone/Sources/StoneException.h"
-#include "../../../OrthancStone/Sources/Toolbox/DicomInstanceParameters.h"
-#include "../../../OrthancStone/Sources/Toolbox/GeometryToolbox.h"
-#include "../../../OrthancStone/Sources/Toolbox/SortedFrames.h"
-#include "../../../OrthancStone/Sources/Viewport/WebGLViewport.h"
+// Stone includes
+#include <Loaders/DicomResourcesLoader.h>
+#include <Loaders/SeriesMetadataLoader.h>
+#include <Loaders/SeriesThumbnailsLoader.h>
+#include <Loaders/WebAssemblyLoadersContext.h>
+#include <Messages/ObserverBase.h>
+#include <Oracle/ParseDicomFromWadoCommand.h>
+#include <Oracle/ParseDicomSuccessMessage.h>
+#include <Scene2D/ColorTextureSceneLayer.h>
+#include <Scene2D/FloatTextureSceneLayer.h>
+#include <Scene2D/PolylineSceneLayer.h>
+#include <StoneException.h>
+#include <Toolbox/DicomInstanceParameters.h>
+#include <Toolbox/GeometryToolbox.h>
+#include <Toolbox/SortedFrames.h>
+#include <Viewport/WebGLViewport.h>
 
 #include <boost/make_shared.hpp>
 #include <stdio.h>
--- a/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake	Thu Aug 13 09:57:35 2020 +0200
+++ b/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake	Thu Aug 13 15:56:01 2020 +0200
@@ -187,6 +187,7 @@
 add_definitions(
   -DHAS_ORTHANC_EXCEPTION=1
   -DORTHANC_STONE_MAX_TAG_LENGTH=256
+  -DORTHANC_BUILDING_STONE_LIBRARY=1
   )
 
 if (CMAKE_BUILD_TYPE STREQUAL "Debug")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancStone/Resources/Orthanc/CMake/EmscriptenParameters.cmake	Thu Aug 13 15:56:01 2020 +0200
@@ -0,0 +1,50 @@
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2020 Osimis S.A., Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+# https://github.com/emscripten-core/emscripten/blob/master/src/settings.js
+
+if (NOT "${EMSCRIPTEN_TRAP_MODE}" STREQUAL "")
+  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s BINARYEN_TRAP_MODE='\"${EMSCRIPTEN_TRAP_MODE}\"'")
+endif()
+
+# "DISABLE_EXCEPTION_CATCHING" is a "compile+link" option. HOWEVER,
+# setting it inside "WASM_FLAGS" creates link errors, at least with
+# side modules. TODO: Understand why
+set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0")
+#set(WASM_FLAGS "${WASM_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0")
+
+if (EMSCRIPTEN_TARGET_MODE STREQUAL "wasm")
+  # WebAssembly
+  set(WASM_FLAGS "${WASM_FLAGS} -s WASM=1")
+  
+elseif (EMSCRIPTEN_TARGET_MODE STREQUAL "asm.js")
+  # asm.js targeting IE 11
+  set(WASM_FLAGS "-s WASM=0 -s ASM_JS=2 -s LEGACY_VM_SUPPORT=1")
+
+else()
+  message(FATAL_ERROR "Bad value for EMSCRIPTEN_TARGET_MODE: ${EMSCRIPTEN_TARGET_MODE}")
+endif()
+
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+  set(WASM_FLAGS "${WASM_FLAGS} -s SAFE_HEAP=1 -s ASSERTIONS=1")
+endif()
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WASM_FLAGS}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WASM_FLAGS}")
--- a/OrthancStone/Resources/SyncOrthancFolder.py	Thu Aug 13 09:57:35 2020 +0200
+++ b/OrthancStone/Resources/SyncOrthancFolder.py	Thu Aug 13 15:56:01 2020 +0200
@@ -18,6 +18,7 @@
     ('OrthancFramework/Resources/CMake/Compiler.cmake',                 'CMake'),
     ('OrthancFramework/Resources/CMake/DownloadOrthancFramework.cmake', 'CMake'),
     ('OrthancFramework/Resources/CMake/DownloadPackage.cmake',          'CMake'),
+    ('OrthancFramework/Resources/CMake/EmscriptenParameters.cmake',     'CMake'),
     ('OrthancFramework/Resources/CMake/GoogleTestConfiguration.cmake',  'CMake'),
     ('OrthancFramework/Resources/EmbedResources.py',                    'CMake'),
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancStone/SharedLibrary/OrthancStone.h.in	Thu Aug 13 15:56:01 2020 +0200
@@ -0,0 +1,63 @@
+#pragma once
+
+/**
+ * Besides the "pragma once" above that only protects this file,
+ * define a macro to prevent including different versions of
+ * "OrthancFramework.h"
+ **/
+#ifndef __ORTHANC_STONE_H
+#define __ORTHANC_STONE_H
+
+#include <OrthancFramework.h>
+
+
+/**
+ * Configuration macros that must be renamed, prefixing them by
+ * "ORTHANC_"
+ **/
+
+#cmakedefine01 ENABLE_WASM
+#if !defined(ENABLE_WASM)
+#  error CMake error
+#elif ENABLE_WASM == 1
+#  define ORTHANC_ENABLE_WASM 1
+#else
+#  define ORTHANC_ENABLE_WASM 0
+#endif
+#undef ENABLE_WASM
+
+#cmakedefine01 ENABLE_OPENGL
+#if !defined(ENABLE_OPENGL)
+#  error CMake error
+#elif ENABLE_OPENGL == 1
+#  define ORTHANC_ENABLE_OPENGL 1
+#else
+#  define ORTHANC_ENABLE_OPENGL 0
+#endif
+#undef ENABLE_OPENGL
+
+#cmakedefine01 ENABLE_SDL
+#if !defined(ENABLE_SDL)
+#  error CMake error
+#elif ENABLE_SDL == 1
+#  define ORTHANC_ENABLE_SDL 1
+#else
+#  define ORTHANC_ENABLE_SDL 0
+#endif
+#undef ENABLE_SDL
+
+
+/**
+ * Fine-tuning
+ **/
+
+#if ORTHANC_ENABLE_OPENGL == 1
+#  define GL_GLEXT_PROTOTYPES 1
+#endif
+
+#if ORTHANC_ENABLE_WASM == 1
+#  define DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR 1
+#endif
+
+
+#endif /* __ORTHANC_STONE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancStone/SharedLibrary/WebAssembly/CMakeLists.txt	Thu Aug 13 15:56:01 2020 +0200
@@ -0,0 +1,175 @@
+cmake_minimum_required(VERSION 2.8.3)
+
+project(OrthancStoneModule)
+
+set(ORTHANC_STONE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/../../../wasm-binaries/OrthancStoneModule" CACHE PATH "Where to put the WebAssembly binaries")
+
+
+# Ask for the generation of a side module
+set(WASM_FLAGS "-s SIDE_MODULE=1 -s EXPORT_ALL=1")  # Must be before "Compiler.cmake"
+
+
+# Configuration of the Emscripten compiler for WebAssembly target
+# ---------------------------------------------------------------
+
+set(USE_WASM ON CACHE BOOL "")
+
+set(EMSCRIPTEN_SET_LLVM_WASM_BACKEND ON CACHE BOOL "")
+
+set(WASM_FLAGS "${WASM_FLAGS} -s WASM=1 -s FETCH=1")
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+  set(WASM_FLAGS "${WASM_FLAGS} -s SAFE_HEAP=1")
+endif()
+
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s ASSERTIONS=1 -s DISABLE_EXCEPTION_CATCHING=0")
+set(WASM_LINKER_FLAGS "${WASM_LINKER_FLAGS} -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1")
+add_definitions(
+  -DDISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1
+)
+
+
+# Stone of Orthanc configuration
+# ---------------------------------------------------------------
+
+include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/OrthancStoneParameters.cmake)
+
+SET(ENABLE_DCMTK ON)
+SET(ENABLE_DCMTK_NETWORKING OFF)
+SET(ENABLE_DCMTK_TRANSCODING OFF)
+SET(ENABLE_GOOGLE_TEST OFF)
+SET(ENABLE_LOCALE ON)  # Necessary for text rendering
+SET(ENABLE_WASM ON)
+SET(ORTHANC_SANDBOXED ON)
+
+include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/OrthancStoneConfiguration.cmake)
+
+
+
+
+################################################################################
+
+# The source files that register a callback cannot be part of a side
+# module, and must be compiled in the main module. The following
+# command can be used to identify such files:
+#  $ grep -l -r emscripten_ ../../Sources/
+
+set(SOURCES_WITH_EMSCRIPTEN_CALLBACKS
+  ${ORTHANC_STONE_ROOT}/Sources/Oracle/WebAssemblyOracle.cpp
+  ${ORTHANC_STONE_ROOT}/Sources/Viewport/WebAssemblyViewport.cpp
+  )
+
+list(REMOVE_ITEM ORTHANC_STONE_SOURCES
+  ${SOURCES_WITH_EMSCRIPTEN_CALLBACKS}
+  )
+
+configure_file(
+  ${CMAKE_SOURCE_DIR}/../OrthancStone.h.in
+  ${CMAKE_CURRENT_BINARY_DIR}/Include/orthanc-stone/OrthancStone.h
+  )
+
+configure_file(
+  ${ORTHANC_FRAMEWORK_ROOT}/../SharedLibrary/OrthancFramework.h.in
+  ${CMAKE_CURRENT_BINARY_DIR}/Include/orthanc-framework/OrthancFramework.h
+  )
+
+file(
+  COPY ${CMAKE_SOURCE_DIR}/../../Sources/
+  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/Include/orthanc-stone
+  NO_SOURCE_PERMISSIONS
+  FILES_MATCHING
+  PATTERN "*.h"
+  PATTERN OrthancStone.h EXCLUDE
+  PATTERN "Deprecated*" EXCLUDE
+  )
+
+file(
+  COPY ${ORTHANC_FRAMEWORK_ROOT}/
+  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/Include/orthanc-framework
+  NO_SOURCE_PERMISSIONS
+  FILES_MATCHING
+  PATTERN "*.h"
+  PATTERN OrthancFramework.h EXCLUDE
+  )
+
+add_executable(OrthancStoneModule
+  ${ORTHANC_STONE_SOURCES}
+  ${AUTOGENERATED_SOURCES}  
+  ${CAIRO_SOURCES}
+  ${PIXMAN_SOURCES}
+  ${FREETYPE_SOURCES}
+  )
+
+set_target_properties(OrthancStoneModule
+  PROPERTIES
+  COMPILE_FLAGS "${WASM_FLAGS}"
+  LINK_FLAGS "${WASM_LINKER_FLAGS}"
+  )
+
+# CMake does not natively handle SIDE_MODULE, and believes that
+# Emscripten produces a ".js" file (whereas it creates only the
+# ".wasm"). Create a dummy ".js" for target to work.
+add_custom_command(
+  TARGET OrthancStoneModule POST_BUILD
+  COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/OrthancStoneModule.js
+  )
+
+file(
+  COPY ${BOOST_SOURCES_DIR}/boost/
+  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/Include/boost/
+  NO_SOURCE_PERMISSIONS
+  FILES_MATCHING
+  PATTERN "*.h"
+  PATTERN "*.hpp"
+  PATTERN "*.ipp"
+  )
+
+file(
+  COPY ${JSONCPP_SOURCES_DIR}/include/json/
+  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/Include/json/
+  NO_SOURCE_PERMISSIONS
+  FILES_MATCHING
+  PATTERN "*.h"
+  )
+
+set(DCMTK_MODULES
+  dcmdata
+  config
+  ofstd
+  oflog
+  )
+
+foreach (module IN LISTS DCMTK_MODULES)
+  file(
+    COPY ${DCMTK_SOURCES_DIR}/ofstd/include/dcmtk/${module}/
+    DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/Include/dcmtk/${module}/
+    NO_SOURCE_PERMISSIONS
+    FILES_MATCHING
+    PATTERN "*.h"
+    )
+endforeach()
+
+    
+install(
+  TARGETS OrthancStoneModule
+  DESTINATION ${ORTHANC_STONE_INSTALL_PREFIX}/lib
+  )
+
+install(FILES
+  ${CMAKE_CURRENT_BINARY_DIR}/OrthancStoneModule.wasm
+  DESTINATION ${ORTHANC_STONE_INSTALL_PREFIX}/lib
+  )
+
+install(
+  DIRECTORY
+  ${CMAKE_CURRENT_BINARY_DIR}/Include/boost
+  ${CMAKE_CURRENT_BINARY_DIR}/Include/dcmtk
+  ${CMAKE_CURRENT_BINARY_DIR}/Include/json
+  ${CMAKE_CURRENT_BINARY_DIR}/Include/orthanc-framework
+  ${CMAKE_CURRENT_BINARY_DIR}/Include/orthanc-stone
+  DESTINATION ${ORTHANC_STONE_INSTALL_PREFIX}/include/
+  )
+
+install(FILES
+  ${SOURCES_WITH_EMSCRIPTEN_CALLBACKS}
+  DESTINATION ${ORTHANC_STONE_INSTALL_PREFIX}/src/orthanc-stone
+  )
--- a/OrthancStone/Sources/Oracle/WebAssemblyOracle.cpp	Thu Aug 13 09:57:35 2020 +0200
+++ b/OrthancStone/Sources/Oracle/WebAssemblyOracle.cpp	Thu Aug 13 15:56:01 2020 +0200
@@ -19,22 +19,14 @@
  **/
 
 
-#include "WebAssemblyOracle.h"
-
-#include "OracleCommandExceptionMessage.h"
-#include "SleepOracleCommand.h"
-
-#if ORTHANC_ENABLE_DCMTK == 1
-#  include "ParseDicomSuccessMessage.h"
-static unsigned int BUCKET_SOP = 1;
+#if defined(ORTHANC_BUILDING_STONE_LIBRARY) && ORTHANC_BUILDING_STONE_LIBRARY == 1
+#  include "WebAssemblyOracle_Includes.h"
+#else
+// This is the case when using the WebAssembly side module, and this
+// source file must be compiled within the WebAssembly main module
+#  include <Oracle/WebAssemblyOracle_Includes.h>
 #endif
 
-#include "GetOrthancImageCommand.h"
-#include "GetOrthancWebViewerJpegCommand.h"
-#include "HttpCommand.h"
-#include "OrthancRestApiCommand.h"
-#include "ParseDicomFromWadoCommand.h"
-
 #include <OrthancException.h>
 #include <Toolbox.h>
 
@@ -42,6 +34,12 @@
 #include <emscripten/html5.h>
 #include <emscripten/fetch.h>
 
+
+#if ORTHANC_ENABLE_DCMTK == 1
+static unsigned int BUCKET_SOP = 1;
+#endif
+
+
 namespace OrthancStone
 {
   class WebAssemblyOracle::TimeoutContext
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancStone/Sources/Oracle/WebAssemblyOracle_Includes.h	Thu Aug 13 15:56:01 2020 +0200
@@ -0,0 +1,42 @@
+/**
+ * Stone of Orthanc
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2020 Osimis S.A., Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Affero General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+/**
+ * This file serves as an indirection to avoid large "#if
+ * ORTHANC_BUILDING_STONE_LIBRARY == 1" in "WebAssemblyOracle.cpp"
+ **/
+
+#include "WebAssemblyOracle.h"
+
+#include "OracleCommandExceptionMessage.h"
+#include "SleepOracleCommand.h"
+
+#if ORTHANC_ENABLE_DCMTK == 1
+#  include "ParseDicomSuccessMessage.h"
+#endif
+
+#include "GetOrthancImageCommand.h"
+#include "GetOrthancWebViewerJpegCommand.h"
+#include "HttpCommand.h"
+#include "OrthancRestApiCommand.h"
+#include "ParseDicomFromWadoCommand.h"
--- a/OrthancStone/Sources/Viewport/WebAssemblyViewport.cpp	Thu Aug 13 09:57:35 2020 +0200
+++ b/OrthancStone/Sources/Viewport/WebAssemblyViewport.cpp	Thu Aug 13 15:56:01 2020 +0200
@@ -19,9 +19,15 @@
  **/
 
 
-#include "WebAssemblyViewport.h"
-
-#include "../Toolbox/GenericToolbox.h"
+#if defined(ORTHANC_BUILDING_STONE_LIBRARY) && ORTHANC_BUILDING_STONE_LIBRARY == 1
+#  include "WebAssemblyViewport.h"
+#  include "../Toolbox/GenericToolbox.h"
+#else
+// This is the case when using the WebAssembly side module, and this
+// source file must be compiled within the WebAssembly main module
+#  include <Viewport/WebAssemblyViewport.h>
+#  include <Toolbox/GenericToolbox.h>
+#endif
 
 #include <OrthancException.h>
 
--- a/OrthancStone/Sources/Viewport/WebAssemblyViewport.h	Thu Aug 13 09:57:35 2020 +0200
+++ b/OrthancStone/Sources/Viewport/WebAssemblyViewport.h	Thu Aug 13 15:56:01 2020 +0200
@@ -21,6 +21,8 @@
 
 #pragma once
 
+#include "../OrthancStone.h"
+
 #if !defined(ORTHANC_ENABLE_WASM)
 #  error Macro ORTHANC_ENABLE_WASM must be defined
 #endif