Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Build
.task
build
cmake-build-*

# IDEs
.idea
.vscode
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "tools/yscope-dev-utils"]
path = tools/yscope-dev-utils
url = https://github.com/y-scope/yscope-dev-utils.git
134 changes: 134 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
cmake_minimum_required(VERSION 3.16)

if(NOT CMAKE_TOOLCHAIN_FILE)
set(CMAKE_TOOLCHAIN_FILE
"${CMAKE_CURRENT_SOURCE_DIR}/build/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake"
)
endif()

set(ZSTD_WASM_PROJECT_NAME "zstd-wasm")

# Extract the project version from package.json
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/package.json")
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/package.json" ZSTD_FFI_JS_PACKAGE_JSON_CONTENT)
else()
message(FATAL_ERROR "`package.json` not found in ${CMAKE_CURRENT_SOURCE_DIR}")
endif()
if("${ZSTD_FFI_JS_PACKAGE_JSON_CONTENT}" MATCHES "\"version\":[ ]*\"([^\"]+)\"")
set(ZSTD_WASM_VERSION "${CMAKE_MATCH_1}")
else()
set(ZSTD_WASM_VERSION "0.0.0")
endif()

project(
"${ZSTD_WASM_PROJECT_NAME}"
LANGUAGES
C
VERSION "${ZSTD_WASM_VERSION}"
)

if(${ZSTD_WASM_PROJECT_NAME}_IS_TOP_LEVEL)
# Include dependency settings if the project isn't being included as a subproject.
# NOTE: We mark the file optional because if the user happens to set the necessary dependency
# location variables, this file is not necessary.
include("build/deps/cmake-settings/settings.cmake" OPTIONAL)
endif()

# Set the default build type to Release if not specified
if(NOT CMAKE_BUILD_TYPE)
set(ZSTD_WASM_DEFAULT_BUILD_TYPE "Release")
message(STATUS "No build type specified. Setting to '${ZSTD_WASM_DEFAULT_BUILD_TYPE}'.")
set(CMAKE_BUILD_TYPE
"${ZSTD_WASM_DEFAULT_BUILD_TYPE}"
CACHE STRING
"Choose the type of build."
FORCE
)
endif()

set(CMAKE_EXECUTABLE_SUFFIX ".js" CACHE STRING "Binary type to be generated by Emscripten.")

# Set up common compile and link options to be merged with other options as necessary.
set(ZSTD_WASM_COMMON_COMPILE_OPTIONS
-fwasm-exceptions
)
set(ZSTD_WASM_EXPORTED_FUNCTIONS
"_free"
"_malloc"
"_ZSTD_createDCtx"
"_ZSTD_decompress"
"_ZSTD_decompressStream"
"_ZSTD_DStreamInSize"
"_ZSTD_DStreamOutSize"
"_ZSTD_findDecompressedSize"
"_ZSTD_freeDCtx"
"_ZSTD_isError"
"_ZSTD_getErrorName"
)
string(JOIN "," ZSTD_WASM_EXPORTED_FUNCTIONS_STR
${ZSTD_WASM_EXPORTED_FUNCTIONS}
)
set(ZSTD_WASM_COMMON_LINK_OPTIONS
-fwasm-exceptions
-sALLOW_MEMORY_GROWTH
-sEXPORT_ES6
-sEXPORTED_RUNTIME_METHODS=["HEAPU8","UTF8ToString"]
-sMAXIMUM_MEMORY=4GB
-sMODULARIZE
-sEXPORTED_FUNCTIONS=[${ZSTD_WASM_EXPORTED_FUNCTIONS_STR}]
)

if(CMAKE_BUILD_TYPE MATCHES "Release")
list(APPEND ZSTD_WASM_COMMON_COMPILE_OPTIONS
-flto
)
list(APPEND ZSTD_WASM_COMMON_LINK_OPTIONS
-flto
--closure=1
)
endif()

set(ZSTD_WASM_SRC_ZSTD
${ZSTD_WASM_ZSTD_SINGLE_FILE_SOURCE_DIRECTORY}/zstd.c
)

set(ZSTD_WASM_SUPPORTED_ENVIRONMENTS
node
worker
CACHE INTERNAL
"List of supported environments."
)

foreach(env ${ZSTD_WASM_SUPPORTED_ENVIRONMENTS})
set(ZSTD_WASM_BIN_NAME "zstd-wasm-${env}")
add_executable(${ZSTD_WASM_BIN_NAME})

# Set up compile options
target_compile_features(${ZSTD_WASM_BIN_NAME} PRIVATE c_std_17)
target_compile_options(${ZSTD_WASM_BIN_NAME} PRIVATE ${ZSTD_WASM_COMMON_COMPILE_OPTIONS})

# Set up link options
set(ZSTD_WASM_LINK_OPTIONS
${ZSTD_WASM_COMMON_LINK_OPTIONS}
--emit-tsd=${ZSTD_WASM_BIN_NAME}.d.ts
-sENVIRONMENT=${env}
)
target_link_options(
${ZSTD_WASM_BIN_NAME}
PRIVATE
${ZSTD_WASM_LINK_OPTIONS}
)

message(
"ZSTD_WASM_BIN_NAME=\"${ZSTD_WASM_BIN_NAME}\". \
CMAKE_BUILD_TYPE=\"${CMAKE_BUILD_TYPE}\". \
Compile options: ${ZSTD_WASM_COMMON_COMPILE_OPTIONS}. \
Link options: ${ZSTD_WASM_LINK_OPTIONS}."
)

target_sources(
${ZSTD_WASM_BIN_NAME}
PRIVATE
${ZSTD_WASM_SRC_ZSTD}
)
endforeach()
89 changes: 89 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
version: "3"

includes:
deps: "taskfiles/deps.yaml"
utils: "tools/yscope-dev-utils/exports/taskfiles/utils/utils.yaml"

vars:
G_BUILD_DIR: "{{.ROOT_DIR}}/build"
G_DEPS_DIR: "{{.G_BUILD_DIR}}/deps"
G_EMSDK_DIR: "{{.G_BUILD_DIR}}/emsdk"
G_ZSTD_WASM_BUILD_DIR: "{{.G_BUILD_DIR}}/zstd-wasm"

G_ZSTD_WASM_ENV_NAMES: ["node", "worker"]
G_ZSTD_WASM_TARGET_PREFIX: "zstd-wasm-"

# These should be kept in-sync with their usage in CMakeLists.txt
G_DEPS_CMAKE_SETTINGS_DIR: "{{.G_DEPS_DIR}}/cmake-settings"
G_DEPS_CMAKE_SETTINGS_FILE: "{{.G_DEPS_CMAKE_SETTINGS_DIR}}/settings.cmake"

G_DEPS_CHECKSUM: "{{.G_BUILD_DIR}}/deps.md5"
G_ZSTD_WASM_CHECKSUM: "{{.G_BUILD_DIR}}/zstd-wasm.md5"

tasks:
default:
deps: ["zstd-wasm"]

clean:
cmds:
- task: "clean-zstd-wasm"
- task: "deps:clean"
- "rm -rf '{{.G_BUILD_DIR}}'"

clean-zstd-wasm:
cmds:
- "rm -rf '{{.G_ZSTD_WASM_BUILD_DIR}}'"

zstd-wasm:
cmds:
- task: "zstd-wasm-generate"
- task: "zstd-wasm-build"

zstd-wasm-generate:
internal: true
sources: &zstd_wasm_source_files
- "{{.G_DEPS_CHECKSUM}}"
- "{{.TASKFILE}}"
- "CMakeLists.txt"
generates:
- "{{.G_ZSTD_WASM_BUILD_DIR}}/CMakeCache.txt"
deps:
- "deps"
cmds:
- task: "utils:cmake:generate"
vars:
BUILD_DIR: "{{.G_ZSTD_WASM_BUILD_DIR}}"
SOURCE_DIR: "{{.ROOT_DIR}}"
EXTRA_ARGS:
- '-DZSTD_WASM_SUPPORTED_ENVIRONMENTS="{{.G_ZSTD_WASM_ENV_NAMES | join ";"}}"'

zstd-wasm-build:
internal: true
vars:
CHECKSUM_FILE: "{{.G_ZSTD_WASM_CHECKSUM}}"
OUTPUT_DIR: "{{.G_ZSTD_WASM_BUILD_DIR}}"
sources: *zstd_wasm_source_files
generates: ["{{.CHECKSUM_FILE}}"]
deps:
- task: "utils:checksum:validate"
vars:
CHECKSUM_FILE: "{{.CHECKSUM_FILE}}"
INCLUDE_PATTERNS: ["{{.OUTPUT_DIR}}"]
cmds:
- task: "utils:cmake:build"
vars:
BUILD_DIR: "{{.OUTPUT_DIR}}"
# Use `--clean-first` to ensure all outputs are rebuilt, since Emscripten's toolchain
# file does not correctly track all generated output files.
EXTRA_ARGS: ["--clean-first"]
# This command must be last
- task: "utils:checksum:compute"
vars:
CHECKSUM_FILE: "{{.CHECKSUM_FILE}}"
INCLUDE_PATTERNS: ["{{.OUTPUT_DIR}}"]

init:
internal: true
silent: true
run: "once"
cmds: ["mkdir -p '{{.G_BUILD_DIR}}'"]
43 changes: 43 additions & 0 deletions docs/src/dev-docs/building-zstd-wasm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Building `zstd-wasm`

This document explains how to build the Zstandard WASM library `zstd-wasm` from source.

## Requirements
* CMake 3.16 or higher
* GNU Make
* Python 3
* [Task] 3.40.0 or higher

## Setup

Initialize and update submodules:

```shell
git submodule update --init --recursive
```

## Build zstd-wasm

To build the zstd-wasm library:

```shell
task zstd-wasm
```

The task first runs `:deps:download-zstd` to fetch the latest Zstandard source code, then executes
`:deps:install-zstd-single-file` to produce the single-file library. Finally, it builds the CMake
project, which uses Emscripten to expose the bindings to JavaScript.

To clean the build:

```shell
task clean-zstd-wasm
```

### Supported Environments

The build system generates separate binaries for different JavaScript environments:
- Node.js
- Web Workers

[Task]: https://taskfile.dev
23 changes: 23 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "@yscope/zstd-ffi-js",
"version": "0.0.1",
"description": "A TypeScript/JavaScript Zstandard library with decompression support and planned compression support",
"type": "module",
"author": "YScope Inc. <dev@yscope.com>",
"license": "Apache-2.0",
"homepage": "https://github.com/y-scope/zstd-ffi-js#readme",
"bugs": {
"url": "https://github.com/y-scope/zstd-ffi-js/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/y-scope/zstd-ffi-js.git"
},
"keywords": [
"zstd",
"zstandard",
"wasm",
"webassembly",
"decompression"
]
}
Loading