Skip to content

Commit

Permalink
Build sherpa-onnx for WebAssembly
Browse files Browse the repository at this point in the history
  • Loading branch information
csukuangfj committed Feb 7, 2024
1 parent 324a265 commit 542fbff
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 64 deletions.
11 changes: 9 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ option(SHERPA_ONNX_ENABLE_JNI "Whether to build JNI internface" OFF)
option(SHERPA_ONNX_ENABLE_C_API "Whether to build C API" ON)
option(SHERPA_ONNX_ENABLE_WEBSOCKET "Whether to build webscoket server/client" ON)
option(SHERPA_ONNX_ENABLE_GPU "Enable ONNX Runtime GPU support" OFF)
option(SHERPA_ONNX_ENABLE_WASM "Whether to enable WASM" OFF)
option(SHERPA_ONNX_ENABLE_BINARY "Whether to build binaries" ON)
option(SHERPA_ONNX_LINK_LIBSTDCPP_STATICALLY "True to link libstdc++ statically. Used only when BUILD_SHARED_LIBS is OFF on Linux" ON)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
Expand Down Expand Up @@ -109,7 +111,7 @@ message(STATUS "C++ Standard version: ${CMAKE_CXX_STANDARD}")

include(CheckIncludeFileCXX)

if(UNIX AND NOT APPLE)
if(UNIX AND NOT APPLE AND NOT SHERPA_ONNX_ENABLE_WASM)
check_include_file_cxx(alsa/asoundlib.h SHERPA_ONNX_HAS_ALSA)
if(SHERPA_ONNX_HAS_ALSA)
add_definitions(-DSHERPA_ONNX_ENABLE_ALSA=1)
Expand Down Expand Up @@ -200,9 +202,14 @@ include(piper-phonemize)

add_subdirectory(sherpa-onnx)

if(SHERPA_ONNX_ENABLE_C_API)
if(SHERPA_ONNX_ENABLE_C_API AND SHERPA_ONNX_ENABLE_BINARY)
add_subdirectory(c-api-examples)
endif()

if(SHERPA_ONNX_ENABLE_WASM)
add_subdirectory(wasm)
endif()

message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")

if(NOT BUILD_SHARED_LIBS)
Expand Down
58 changes: 58 additions & 0 deletions build-wasm-simd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env bash
# Copyright (c) 2024 Xiaomi Corporation
#
# This script is to build sherpa-onnx for WebAssembly

set -ex

if [ x"$EMSCRIPTEN" == x"" ]; then
if ! command -v emcc &> /dev/null; then
echo "Please install emscripten first"
echo ""
echo "You can use the following commands to install it:"
echo ""
echo "git clone https://github.com/emscripten-core/emsdk.git"
echo "cd emsdk"
echo "git pull"
echo "./emsdk install latest"
echo "./emsdk activate latest"
echo "source ./emsdk_env.sh"
exit 1
else
EMSCRIPTEN=$(dirname $(realpath $(which emcc)))
fi
fi

export EMSCRIPTEN=$EMSCRIPTEN
echo "EMSCRIPTEN: $EMSCRIPTEN"
if [ ! -f $EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake ]; then
echo "Cannot find $EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake"
echo "Please make sure you have installed emsdk correctly"
exit 1
fi

mkdir -p build-wasm-simd
pushd build-wasm-simd

export SHERPA_ONNX_IS_USING_BUILD_WASM_SH=ON

cmake \
-DCMAKE_INSTALL_PREFIX=./install \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=$EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake \
\
-DSHERPA_ONNX_ENABLE_PYTHON=OFF \
-DSHERPA_ONNX_ENABLE_TESTS=OFF \
-DSHERPA_ONNX_ENABLE_CHECK=OFF \
-DBUILD_SHARED_LIBS=OFF \
-DSHERPA_ONNX_ENABLE_PORTAUDIO=OFF \
-DSHERPA_ONNX_ENABLE_JNI=OFF \
-DSHERPA_ONNX_ENABLE_C_API=ON \
-DSHERPA_ONNX_ENABLE_WEBSOCKET=OFF \
-DSHERPA_ONNX_ENABLE_GPU=OFF \
-DSHERPA_ONNX_ENABLE_WASM=ON \
-DSHERPA_ONNX_ENABLE_BINARY=OFF \
-DSHERPA_ONNX_LINK_LIBSTDCPP_STATICALLY=OFF \
..
make -j2
make install
20 changes: 12 additions & 8 deletions cmake/espeak-ng-for-piper.cmake
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
function(download_espeak_ng_for_piper)
include(FetchContent)

set(espeak_ng_URL "https://github.com/csukuangfj/espeak-ng/archive/c58d2a4a88e9a291ca448f046e15c6188cbd3b3a.zip")
set(espeak_ng_URL2 "")
set(espeak_ng_HASH "SHA256=8a48251e6926133dd91fcf6cb210c7c2e290a9b578d269446e2d32d710b0dfa0")
set(espeak_ng_URL "https://github.com/csukuangfj/espeak-ng/archive/69bf6927964fb042aeb827cfdf6082a30f5802eb.zip")
set(espeak_ng_URL2 "https://hub.nuaa.cf/csukuangfj/espeak-ng/archive/69bf6927964fb042aeb827cfdf6082a30f5802eb.zip")
set(espeak_ng_HASH "SHA256=745e35b21ece6804b4a1839722f9e625ac909380c8f85873ad71bf145877075a")

set(BUILD_ESPEAK_NG_TESTS OFF CACHE BOOL "" FORCE)
set(USE_ASYNC OFF CACHE BOOL "" FORCE)
Expand All @@ -15,14 +15,18 @@ function(download_espeak_ng_for_piper)
set(EXTRA_cmn ON CACHE BOOL "" FORCE)
set(EXTRA_ru ON CACHE BOOL "" FORCE)

if(SHERPA_ONNX_ENABLE_WASM)
set(BUILD_ESPEAK_NG_EXE OFF CACHE BOOL "" FORCE)
endif()

# If you don't have access to the Internet,
# please pre-download kaldi-decoder
set(possible_file_locations
$ENV{HOME}/Downloads/espeak-ng-c58d2a4a88e9a291ca448f046e15c6188cbd3b3a.zip
${CMAKE_SOURCE_DIR}/espeak-ng-c58d2a4a88e9a291ca448f046e15c6188cbd3b3a.zip
${CMAKE_BINARY_DIR}/espeak-ng-c58d2a4a88e9a291ca448f046e15c6188cbd3b3a.zip
/tmp/espeak-ng-c58d2a4a88e9a291ca448f046e15c6188cbd3b3a.zip
/star-fj/fangjun/download/github/espeak-ng-c58d2a4a88e9a291ca448f046e15c6188cbd3b3a.zip
$ENV{HOME}/Downloads/espeak-ng-69bf6927964fb042aeb827cfdf6082a30f5802eb.zip
${CMAKE_SOURCE_DIR}/espeak-ng-69bf6927964fb042aeb827cfdf6082a30f5802eb.zip
${CMAKE_BINARY_DIR}/espeak-ng-69bf6927964fb042aeb827cfdf6082a30f5802eb.zip
/tmp/espeak-ng-69bf6927964fb042aeb827cfdf6082a30f5802eb.zip
/star-fj/fangjun/download/github/espeak-ng-69bf6927964fb042aeb827cfdf6082a30f5802eb.zip
)

foreach(f IN LISTS possible_file_locations)
Expand Down
16 changes: 8 additions & 8 deletions cmake/kaldi-decoder.cmake
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
function(download_kaldi_decoder)
include(FetchContent)

set(kaldi_decoder_URL "https://github.com/k2-fsa/kaldi-decoder/archive/refs/tags/v0.2.3.tar.gz")
set(kaldi_decoder_URL2 "https://huggingface.co/csukuangfj/sherpa-onnx-cmake-deps/resolve/main/kaldi-decoder-0.2.3.tar.gz")
set(kaldi_decoder_HASH "SHA256=98bf445a5b7961ccf3c3522317d900054eaadb6a9cdcf4531e7d9caece94a56d")
set(kaldi_decoder_URL "https://github.com/k2-fsa/kaldi-decoder/archive/refs/tags/v0.2.4.tar.gz")
set(kaldi_decoder_URL2 "https://hub.nuaa.cf/k2-fsa/kaldi-decoder/archive/refs/tags/v0.2.4.tar.gz")
set(kaldi_decoder_HASH "SHA256=136d96c2f1f8ec44de095205f81a6ce98981cd867fe4ba840f9415a0b58fe601")

set(KALDI_DECODER_BUILD_PYTHON OFF CACHE BOOL "" FORCE)
set(KALDI_DECODER_ENABLE_TESTS OFF CACHE BOOL "" FORCE)
Expand All @@ -12,11 +12,11 @@ function(download_kaldi_decoder)
# If you don't have access to the Internet,
# please pre-download kaldi-decoder
set(possible_file_locations
$ENV{HOME}/Downloads/kaldi-decoder-0.2.3.tar.gz
${CMAKE_SOURCE_DIR}/kaldi-decoder-0.2.3.tar.gz
${CMAKE_BINARY_DIR}/kaldi-decoder-0.2.3.tar.gz
/tmp/kaldi-decoder-0.2.3.tar.gz
/star-fj/fangjun/download/github/kaldi-decoder-0.2.3.tar.gz
$ENV{HOME}/Downloads/kaldi-decoder-0.2.4.tar.gz
${CMAKE_SOURCE_DIR}/kaldi-decoder-0.2.4.tar.gz
${CMAKE_BINARY_DIR}/kaldi-decoder-0.2.4.tar.gz
/tmp/kaldi-decoder-0.2.4.tar.gz
/star-fj/fangjun/download/github/kaldi-decoder-0.2.4.tar.gz
)

foreach(f IN LISTS possible_file_locations)
Expand Down
16 changes: 8 additions & 8 deletions cmake/kaldifst.cmake
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
function(download_kaldifst)
include(FetchContent)

set(kaldifst_URL "https://github.com/k2-fsa/kaldifst/archive/refs/tags/v1.7.9.tar.gz")
set(kaldifst_URL2 "https://huggingface.co/csukuangfj/kaldi-hmm-gmm-cmake-deps/resolve/main/kaldifst-1.7.9.tar.gz")
set(kaldifst_HASH "SHA256=8c653021491dca54c38ab659565edfab391418a79ae87099257863cd5664dd39")
set(kaldifst_URL "https://github.com/k2-fsa/kaldifst/archive/refs/tags/v1.7.10.tar.gz")
set(kaldifst_URL2 "https://hub.nuaa.cf/k2-fsa/kaldifst/archive/refs/tags/v1.7.10.tar.gz")
set(kaldifst_HASH "SHA256=7f7b3173a6584a6b1987f65ae7af2ac453d66b845f875a9d31074b8d2cd0de54")

# If you don't have access to the Internet,
# please pre-download kaldifst
set(possible_file_locations
$ENV{HOME}/Downloads/kaldifst-1.7.9.tar.gz
${CMAKE_SOURCE_DIR}/kaldifst-1.7.9.tar.gz
${CMAKE_BINARY_DIR}/kaldifst-1.7.9.tar.gz
/tmp/kaldifst-1.7.9.tar.gz
/star-fj/fangjun/download/github/kaldifst-1.7.9.tar.gz
$ENV{HOME}/Downloads/kaldifst-1.7.10.tar.gz
${CMAKE_SOURCE_DIR}/kaldifst-1.7.10.tar.gz
${CMAKE_BINARY_DIR}/kaldifst-1.7.10.tar.gz
/tmp/kaldifst-1.7.10.tar.gz
/star-fj/fangjun/download/github/kaldifst-1.7.10.tar.gz
)

foreach(f IN LISTS possible_file_locations)
Expand Down
60 changes: 60 additions & 0 deletions cmake/onnxruntime-wasm-simd.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Copyright (c) 2022-2024 Xiaomi Corporation
message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")

if(NOT SHERPA_ONNX_ENABLE_WASM)
message(FATAL_ERROR "This file is for WebAssembly.")
endif()

if(BUILD_SHARED_LIBS)
message(FATAL_ERROR "BUILD_SHARED_LIBS should be OFF for WebAssembly")
endif()

set(onnxruntime_URL "https://github.com/csukuangfj/onnxruntime-libs/releases/download/v1.16.3/onnxruntime-wasm-static_lib-simd-1.16.3.zip")
set(onnxruntime_URL2 "https://hub.nuaa.cf/csukuangfj/onnxruntime-libs/releases/download/v1.16.3/onnxruntime-wasm-static_lib-simd-1.16.3.zip")
set(onnxruntime_HASH "SHA256=f2be5987fc6b53a8a8b80889c3a70fe82d36c3b0ab6c53121078cd3aa95dd6a4")

# If you don't have access to the Internet,
# please download onnxruntime to one of the following locations.
# You can add more if you want.
set(possible_file_locations
$ENV{HOME}/Downloads/onnxruntime-wasm-static_lib-simd-1.16.3.zip
${CMAKE_SOURCE_DIR}/onnxruntime-wasm-static_lib-simd-1.16.3.zip
${CMAKE_BINARY_DIR}/onnxruntime-wasm-static_lib-simd-1.16.3.zip
/tmp/onnxruntime-wasm-static_lib-simd-1.16.3.zip
/star-fj/fangjun/download/github/onnxruntime-wasm-static_lib-simd-1.16.3.zip
)

foreach(f IN LISTS possible_file_locations)
if(EXISTS ${f})
set(onnxruntime_URL "${f}")
file(TO_CMAKE_PATH "${onnxruntime_URL}" onnxruntime_URL)
message(STATUS "Found local downloaded onnxruntime: ${onnxruntime_URL}")
set(onnxruntime_URL2)
break()
endif()
endforeach()

FetchContent_Declare(onnxruntime
URL
${onnxruntime_URL}
${onnxruntime_URL2}
URL_HASH ${onnxruntime_HASH}
)

FetchContent_GetProperties(onnxruntime)
if(NOT onnxruntime_POPULATED)
message(STATUS "Downloading onnxruntime from ${onnxruntime_URL}")
FetchContent_Populate(onnxruntime)
endif()
message(STATUS "onnxruntime is downloaded to ${onnxruntime_SOURCE_DIR}")

# for static libraries, we use onnxruntime_lib_files directly below
include_directories(${onnxruntime_SOURCE_DIR}/include)

file(GLOB onnxruntime_lib_files "${onnxruntime_SOURCE_DIR}/lib/lib*.a")

set(onnxruntime_lib_files ${onnxruntime_lib_files} PARENT_SCOPE)

message(STATUS "onnxruntime lib files: ${onnxruntime_lib_files}")
install(FILES ${onnxruntime_lib_files} DESTINATION lib)
5 changes: 3 additions & 2 deletions cmake/onnxruntime.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ function(download_onnxruntime)

message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")

if(CMAKE_SYSTEM_NAME STREQUAL Linux AND CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
if(SHERPA_ONNX_ENABLE_WASM)
include(onnxruntime-wasm-simd)
elseif(CMAKE_SYSTEM_NAME STREQUAL Linux AND CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
if(BUILD_SHARED_LIBS)
include(onnxruntime-linux-aarch64)
else()
Expand Down
77 changes: 41 additions & 36 deletions sherpa-onnx/csrc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,6 @@ if(APPLE)
)
endif()

if(NOT WIN32)
target_link_libraries(sherpa-onnx-core -pthread)
endif()

if(ANDROID_NDK)
target_link_libraries(sherpa-onnx-core android log)
Expand Down Expand Up @@ -172,36 +169,42 @@ if(SHERPA_ONNX_ENABLE_CHECK)
endif()

if(NOT BUILD_SHARED_LIBS AND CMAKE_SYSTEM_NAME STREQUAL Linux)
target_link_libraries(sherpa-onnx-core -pthread -ldl)
target_link_libraries(sherpa-onnx-core -ldl)
endif()

add_executable(sherpa-onnx sherpa-onnx.cc)
add_executable(sherpa-onnx-keyword-spotter sherpa-onnx-keyword-spotter.cc)
add_executable(sherpa-onnx-offline sherpa-onnx-offline.cc)
add_executable(sherpa-onnx-offline-parallel sherpa-onnx-offline-parallel.cc)
add_executable(sherpa-onnx-offline-tts sherpa-onnx-offline-tts.cc)

set(main_exes
sherpa-onnx
sherpa-onnx-keyword-spotter
sherpa-onnx-offline
sherpa-onnx-offline-parallel
sherpa-onnx-offline-tts
)
if(NOT WIN32 AND NOT SHERPA_ONNX_ENABLE_WASM AND NOT BUILD_SHARED_LIBS)
target_link_libraries(sherpa-onnx-core -pthread)
endif()

foreach(exe IN LISTS main_exes)
target_link_libraries(${exe} sherpa-onnx-core)
endforeach()
if(SHERPA_ONNX_ENABLE_BINARY)
add_executable(sherpa-onnx sherpa-onnx.cc)
add_executable(sherpa-onnx-keyword-spotter sherpa-onnx-keyword-spotter.cc)
add_executable(sherpa-onnx-offline sherpa-onnx-offline.cc)
add_executable(sherpa-onnx-offline-parallel sherpa-onnx-offline-parallel.cc)
add_executable(sherpa-onnx-offline-tts sherpa-onnx-offline-tts.cc)

set(main_exes
sherpa-onnx
sherpa-onnx-keyword-spotter
sherpa-onnx-offline
sherpa-onnx-offline-parallel
sherpa-onnx-offline-tts
)

if(NOT WIN32)
foreach(exe IN LISTS main_exes)
target_link_libraries(${exe} "-Wl,-rpath,${SHERPA_ONNX_RPATH_ORIGIN}/../lib")
target_link_libraries(${exe} "-Wl,-rpath,${SHERPA_ONNX_RPATH_ORIGIN}/../../../sherpa_onnx/lib")

if(SHERPA_ONNX_ENABLE_PYTHON)
target_link_libraries(${exe} "-Wl,-rpath,${SHERPA_ONNX_RPATH_ORIGIN}/../lib/python${PYTHON_VERSION}/site-packages/sherpa_onnx/lib")
endif()
target_link_libraries(${exe} sherpa-onnx-core)
endforeach()

if(NOT WIN32)
foreach(exe IN LISTS main_exes)
target_link_libraries(${exe} "-Wl,-rpath,${SHERPA_ONNX_RPATH_ORIGIN}/../lib")
target_link_libraries(${exe} "-Wl,-rpath,${SHERPA_ONNX_RPATH_ORIGIN}/../../../sherpa_onnx/lib")

if(SHERPA_ONNX_ENABLE_PYTHON)
target_link_libraries(${exe} "-Wl,-rpath,${SHERPA_ONNX_RPATH_ORIGIN}/../lib/python${PYTHON_VERSION}/site-packages/sherpa_onnx/lib")
endif()
endforeach()
endif()
endif()

if(SHERPA_ONNX_ENABLE_PYTHON AND WIN32)
Expand All @@ -214,14 +217,16 @@ if(WIN32 AND BUILD_SHARED_LIBS)
install(TARGETS sherpa-onnx-core DESTINATION bin)
endif()

install(
TARGETS
${main_exes}
DESTINATION
bin
)
if(SHERPA_ONNX_ENABLE_BINARY)
install(
TARGETS
${main_exes}
DESTINATION
bin
)
endif()

if(SHERPA_ONNX_HAS_ALSA)
if(SHERPA_ONNX_HAS_ALSA AND SHERPA_ONNX_ENABLE_BINARY)
add_executable(sherpa-onnx-alsa sherpa-onnx-alsa.cc alsa.cc)
add_executable(sherpa-onnx-offline-tts-play-alsa sherpa-onnx-offline-tts-play-alsa.cc alsa-play.cc)

Expand Down Expand Up @@ -261,7 +266,7 @@ if(SHERPA_ONNX_HAS_ALSA)
)
endif()

if(SHERPA_ONNX_ENABLE_PORTAUDIO)
if(SHERPA_ONNX_ENABLE_PORTAUDIO AND SHERPA_ONNX_ENABLE_BINARY)
add_executable(sherpa-onnx-offline-tts-play
sherpa-onnx-offline-tts-play.cc
microphone.cc
Expand Down Expand Up @@ -330,7 +335,7 @@ if(SHERPA_ONNX_ENABLE_PORTAUDIO)
)
endif()

if(SHERPA_ONNX_ENABLE_WEBSOCKET)
if(SHERPA_ONNX_ENABLE_WEBSOCKET AND SHERPA_ONNX_ENABLE_BINARY)
add_definitions(-DASIO_STANDALONE)
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)

Expand Down

0 comments on commit 542fbff

Please sign in to comment.