Skip to content

Commit

Permalink
Enable building as a WASM object with emscripten.
Browse files Browse the repository at this point in the history
Only tested with, and includes some specifics for, the emscripten toolchain.
  • Loading branch information
gfiumara committed Aug 11, 2023
1 parent cf5f4ac commit 298344b
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
14 changes: 14 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ option(WITH_HWLOC "Build sources that require libhwloc" ON)
option(WITH_MPI "Build sources that require MPI" ON)
# Build sources that require PCSC
option(WITH_PCSC "Build sources that require PCSC" ON)
# Disable things that aren't well supported under WASM
option(BUILD_FOR_WASM "Build in a way that supports WASM" OFF)
# Auto-enable WASM build if we can detect emscripten
if (BUILD_FOR_WASM)
message(STATUS "Disabling unsupported components to enable WASM build")
elseif(EMSCRIPTEN)
message(STATUS "Emscripten detected, enabling WASM by disabling unsupported components")
set(BUILD_FOR_WASM ON)
endif(BUILD_FOR_WASM)
# Use WASM exceptions (over JavaScript exceptions)
cmake_dependent_option(WASM_EXCEPTIONS "Use WASM exceptions (instead of JavaScript exceptions)" ON "BUILD_FOR_WASM;EMSCRIPTEN" OFF)
if (WASM_EXCEPTIONS)
message(STATUS "Enabling WebAssembly exception handling")
endif (WASM_EXCEPTIONS)

# Build sources that require FFMPEG. FFMPEG has *many* dynamic dependencies that
# aren't built static on all systems, therefore we cannot guarantee they'll be
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,16 +200,22 @@ Options
The CMake build supports the following options:
| CMake Option | Default | Description | Notes |
|:-----------------------:|:-------:|:----------------------------------------------------:|:-----:|
|:------------------------|:-------:|:-----------------------------------------------------|:------|
| `BUILD_BIOMEVAL_32BIT` | `OFF` | Compile 32-bit on 64-bit host OS ||
| `BUILD_BIOMEVAL_TESTS` | `OFF` | Build test programs ||
| `BUILD_FOR_WASM` | `OFF` | Disable components currently not supported under WebAssembly | Defaults to `ON` when the [Emscripten](https://emscripten.org) toolchain is detected |
| `BUILD_SHARED_LIBS` | `OFF` | Build shared library (i.e., `.so`, `.dll`, `.dylib`) | When `OFF`, a static library (i.e., `.a`, `.lib`) is built instead |
| `FORCE_STATIC_DEPENDENCIES` | `OFF` | Force linking against `.a`/`.lib` third-party dependencies. | Unavailable on Windows (use `-DBUILD_SHARED_LIBS=OFF` for similar behavior) |
| `WASM_EXCEPTIONS` | `ON` | When compiled to WebAssembly, use WebAssembly exceptions instead of JavaScript exceptions | Only available when `BUILD_FOR_WASM` is `YES` and the [Emscripten](https://emscripten.org) toolchain is detected |
| `WITH_FFMPEG` | `ON` | Build sources that require [FFMPEG](https://ffmpeg.org) | Unavailable when `FORCE_STATIC_DEPENDENCIES` is `ON` |
| `WITH_HWLOC` | `ON` | Build sources that require [libhwloc](https://www.open-mpi.org/projects/hwloc/) |
| `WITH_MPI` | `ON` | Build sources that require [OpenMPI](https://www.open-mpi.org/) |
| `WITH_PCSC` | `ON` | Build sources that require [PCSC](https://pcsclite.apdu.fr) |
### A Note about WebAssembly
A minimal version of the library can be compiled to WebAssembly and is supported. Compilation has only been tested using the [Emscripten](https://emscripten.org) toolchain. When this toolchain is detected (i.e., when `emcmake` is used to configure, rather than `cmake`), the above options for WebAssembly are automatically enabled.
---
As Seen In...
Expand Down
35 changes: 35 additions & 0 deletions src/libbiomeval/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,23 @@

cmake_minimum_required(VERSION 2.8.11)

if (BUILD_FOR_WASM)
add_definitions("-DWASM")
if (EMSCRIPTEN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -sUSE_LIBPNG=1 -sUSE_LIBJPEG=1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -sUSE_LIBPNG=1 -sUSE_LIBJPEG=1")

if (WASM_EXCEPTIONS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -sSUPPORT_LONGJMP=wasm")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fwasm-exceptions")
set(LDFLAGS "${LDFLAGS} -fwasm-exceptions")
set(PNG_NAMES "png-wasm-sjlj")
endif (WASM_EXCEPTIONS)
endif (EMSCRIPTEN)

set(WITH_HWLOC OFF)
endif()

if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" AND FORCE_STATIC_DEPENDENCIES)
# No static libhwloc in MacPorts
set(WITH_HWLOC OFF)
Expand Down Expand Up @@ -193,6 +210,16 @@ endif(MSVC)
# VIDEO if the required libraries are present.
#
set(PACKAGES ${CORE} ${IO} ${RECORDSTORE} ${IMAGE} ${FEATURE} ${VIEW} ${DATA} ${FINGER} ${PALM} ${PLANTAR} ${IRIS} ${FACE} ${PROCESS} ${MESSAGE_CENTER})
if (BUILD_FOR_WASM)
# We're not concerned with these packages for WebAssembly
list(REMOVE_ITEM PACKAGES ${PROCESS} ${MESSAGE_CENTER})

# XXX: Remove RecordStore support simply to reduce the number of
# dependencies that need to be recompiled for the WASM
# architecture. It is likely they can be added back in the future.
list(REMOVE_ITEM PACKAGES ${RECORDSTORE})
endif (BUILD_FOR_WASM)


if (WITH_FFMPEG)
# Our FindFFMPEG.cmake is not sufficient for finding all of FFMPEG's
Expand Down Expand Up @@ -412,13 +439,17 @@ endif (MSVC)
# For OS-X, add paths where the ports packages are placed.
#
if(CMAKE_HOST_APPLE)
if (NOT BUILD_FOR_WASM)
target_include_directories(coreobjs PUBLIC /opt/local/include)
set_target_properties(${CORELIB} PROPERTIES MACOSX_RPATH ON)
target_link_libraries(${CORELIB} -L/opt/local/lib)
endif (NOT BUILD_FOR_WASM)
if (PCSC_FOUND)
target_link_libraries(${CORELIB} ${PCSC_FRAMEWORK})
endif (PCSC_FOUND)
if (NOT BUILD_FOR_WASM)
add_definitions("-DDarwin")
endif(NOT BUILD_FOR_WASM)
endif(CMAKE_HOST_APPLE)

target_include_directories(coreobjs PUBLIC ${BIOMEVAL_INCLUDE} ${NBIS_INCLUDE})
Expand Down Expand Up @@ -460,13 +491,15 @@ endif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" AND BLOCK_SUPPORT)
#
# Berkeley DB
#
if (NOT BUILD_FOR_WASM)
set(BERKELEYDB_FIND_REQUIRED TRUE)
find_package(BERKELEYDB)
if(NOT BERKELEYDB_FOUND)
message(FATAL_ERROR "Could not find Berkeley Database.")
endif(NOT BERKELEYDB_FOUND)
include_directories(PUBLIC ${BERKELEYDB_INCLUDE_DIR})
target_link_libraries(${CORELIB} ${BERKELEYDB_LIBRARIES})
endif()

#
# OpenJPEG and JPEG2000
Expand Down Expand Up @@ -530,9 +563,11 @@ endif (WITH_HWLOC)
target_link_libraries(${CORELIB}
$<$<AND:$<CXX_COMPILER_ID:GNU>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,9.0>>:stdc++fs>)

if (NOT BUILD_FOR_WASM)
# This will use our Module
find_package(SQLITE3 REQUIRED)
target_link_libraries(${CORELIB} ${SQLITE3_LIBRARIES})
endif()

# libtiff, like ffmpeg, writes a pkg-config, but it prefers to link against
# shared libs. We can't have that with this option.
Expand Down

0 comments on commit 298344b

Please sign in to comment.