Skip to content

Commit 484792d

Browse files
committed
experiment: add Webassembly support
Depends on EmbeddedEnterprises/cmake-ts#61
1 parent 33f19d3 commit 484792d

File tree

11 files changed

+1930
-14
lines changed

11 files changed

+1930
-14
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,6 @@ compile_commands.json
3030
/smoke-test-*
3131
/*.tgz
3232
/build-artifacts
33+
.parcel-cache/
34+
dist/
35+
*.wasm

CMakeLists.txt

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,42 @@ if(${ZMQ_ENABLE_SANITIZER_UNDEFINED})
7474
set(ENABLE_SANITIZER_UNDEFINED "ENABLE_SANITIZER_UNDEFINED")
7575
endif()
7676

77+
option(ZMQ_WASM "Build for WebAssembly" OFF)
78+
set_option_from_env(ZMQ_WASM)
79+
80+
if(ZMQ_WASM OR CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
81+
set(ZMQ_WASM TRUE)
82+
83+
# Compile for WebAssembly
84+
set(VCPKG_HOST_TRIPLET wasm32-emscripten)
85+
set(VCPKG_TARGET_TRIPLET wasm32-emscripten)
86+
87+
include($ENV{EMSCRIPTEN_ROOT}/cmake/Modules/Platform/Emscripten.cmake)
88+
89+
set(CMAKE_LINKER "$ENV{EMSCRIPTEN_ROOT}/bin/lld${CMAKE_EXECUTABLE_SUFFIX}" CACHE STRING "Linker" FORCE)
90+
91+
# export an indirect function table for napi-wasm
92+
add_link_options("--export-table")
93+
94+
# Add WebAssembly-specific exports for napi-wasm
95+
add_link_options("SHELL:-s EXPORTED_FUNCTIONS=['_malloc','_free','napi_wasm_malloc','napi_register_module_v1']")
96+
add_link_options("SHELL:-s EXPORTED_RUNTIME_METHODS=['ccall','cwrap']")
97+
add_link_options("SHELL:-s ALLOW_MEMORY_GROWTH=1")
98+
add_link_options("SHELL:-s MODULARIZE=1")
99+
add_link_options("SHELL:-s EXPORT_NAME='createModule'")
100+
add_link_options("SHELL:-s ENVIRONMENT='web,worker'")
101+
add_link_options("--no-entry")
102+
add_link_options("SHELL:-Wl,--strip-all")
103+
add_link_options("SHELL:-fvisibility=hidden")
104+
add_link_options("SHELL:-fvisibility-inlines-hidden")
105+
add_link_options("SHELL:-Wl,-gc-sections")
106+
add_compile_options("-flto=full")
107+
add_link_options("-flto=full")
108+
109+
# Allow undefined symbols on Linux for runtime loading
110+
add_link_options("SHELL:-Wl,--unresolved-symbols=ignore-all")
111+
endif()
112+
77113
# Set MacOS deployment target
78114
if(APPLE)
79115
option(MACOSX_DEPLOYMENT_TARGET "MacOS deployment target" "10.15")
@@ -126,8 +162,14 @@ project_options(
126162
${ENABLE_SANITIZER_UNDEFINED}
127163
)
128164

129-
file(GLOB_RECURSE SOURCES "./src/*.cc")
130-
add_library(addon SHARED ${SOURCES})
165+
file(GLOB_RECURSE SOURCES "./src/*.cc" "./src/*.cpp")
166+
167+
if(ZMQ_WASM)
168+
# For WebAssembly, create an executable instead of a shared library
169+
add_executable(addon ${SOURCES})
170+
else()
171+
add_library(addon SHARED ${SOURCES})
172+
endif()
131173

132174
if(CMAKE_CXX_COMPILER_ID STREQUAL GNU
133175
OR CMAKE_CXX_COMPILER_ID STREQUAL Clang
@@ -145,6 +187,10 @@ if(ZMQ_NO_SYNC_RESOLVE)
145187
target_compile_definitions(addon PRIVATE ZMQ_NO_SYNC_RESOLVE)
146188
endif()
147189

190+
if(ZMQ_WASM)
191+
target_compile_definitions(addon PRIVATE ZMQ_WASM)
192+
endif()
193+
148194
# ZeroMQ
149195
find_package(ZeroMQ CONFIG REQUIRED)
150196
target_link_system_libraries(addon PRIVATE libzmq libzmq-static)
@@ -168,7 +214,11 @@ if(WIN32)
168214
endif()
169215

170216
# Use `.node` for the library without any "lib" prefix
171-
set_target_properties(addon PROPERTIES PREFIX "" SUFFIX ".node")
217+
if(ZMQ_WASM)
218+
set_target_properties(addon PROPERTIES PREFIX "" SUFFIX ".wasm")
219+
else()
220+
set_target_properties(addon PROPERTIES PREFIX "" SUFFIX ".node")
221+
endif()
172222

173223
# Windows delay load node.exe
174224
if(WIN32)

browser/index.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<title>ZeroMQ</title>
4+
<body>
5+
<script type="module" src="./index.js"></script>
6+
</body>
7+
</html>

browser/index.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import {Environment, napi} from "napi-wasm"
2+
3+
async function main() {
4+
const response = await fetch("./addon.wasm")
5+
const bytes = await response.arrayBuffer()
6+
const {instance} = await WebAssembly.instantiate(
7+
bytes,
8+
{
9+
env: napi,
10+
},
11+
)
12+
13+
// Create an environment.
14+
let env = new Environment(instance)
15+
let exports = env.exports
16+
17+
console.log(exports)
18+
}
19+
20+
main().catch(err => {
21+
throw err
22+
})

browser/package.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "browser",
3+
"version": "1.0.0",
4+
"description": "",
5+
"scripts": {
6+
"start": "parcel index.html"
7+
},
8+
"keywords": [],
9+
"author": "",
10+
"license": "ISC",
11+
"packageManager": "[email protected]",
12+
"devDependencies": {
13+
"parcel": "^2.15.4"
14+
}
15+
}

0 commit comments

Comments
 (0)