Skip to content

Commit

Permalink
Add infrastructure to build WebAssembly static libs via wasm-vips
Browse files Browse the repository at this point in the history
Co-authored-by: Ingvar Stepanyan <[email protected]>
  • Loading branch information
lovell and RReverser committed Nov 7, 2023
1 parent c57d14e commit f5c3871
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 2 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
- 'linuxmusl-x64'
- 'linuxmusl-arm64v8'
- 'linux-s390x'
- 'wasm32'
- 'win32-ia32'
- 'win32-x64'
- 'win32-arm64v8'
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
libvips*
*.log
build/wasm-vips-*
deps/
target/
npm/*/*
!npm/*/package.json
!npm/dev-wasm32/THIRD-PARTY-NOTICES.md
npm/img-sharp-libvips-*.tgz
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ The dylib files are compiled within the same build script as Linux.

Dependency paths are modified to use the relative `@rpath` with `install_name_tool`.

### WebAssembly

The scripts from [wasm-vips](https://github.com/kleisauke/wasm-vips)
are [used to compile](build/wasm.sh) libvips and its dependencies
as static Wasm libraries ready for further compilation into a single,
statically-linked sharp shared library.

## Licences

These scripts are licensed under the terms of the [Apache 2.0 Licence](LICENSE).
Expand Down
6 changes: 6 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ if ! [ -x "$(command -v docker)" ]; then
exit 1
fi

# WebAssembly
if [ "$PLATFORM" == "wasm32" ]; then
./build/wasm.sh "${VERSION_VIPS}"
exit 0
fi

# Update base images
for baseimage in alpine:3.15 amazonlinux:2 debian:bullseye debian:buster; do
docker pull $baseimage
Expand Down
50 changes: 50 additions & 0 deletions build/wasm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env bash
set -e

if [ $# -lt 1 ]; then
echo
echo "Usage: $0 VERSION_VIPS [VERSION_WASM_VIPS]"
echo "Use wasm-vips to build wasm32 static libraries for libvips and its dependencies"
echo
echo "Please specify the libvips VERSION_VIPS, e.g. 8.15.0"
echo "Optionally provide a specific VERSION_WASM_VIPS commit, e.g. abc1234"
echo
exit 1
fi
VERSION_VIPS="$1"
VERSION_WASM_VIPS="${2:-56f151b}" # TODO: fetch latest wasm-vips commit as default

DIR="wasm-vips-${VERSION_WASM_VIPS}"
TAG="wasm-vips:${VERSION_WASM_VIPS}"

echo "Using ${TAG} to build libvips ${VERSION_VIPS}"
cd "${0%/*}"

# Download specific version of wasm-vips
if [ ! -d "$DIR" ]; then
mkdir "${DIR}"
curl -Ls https://github.com/kleisauke/wasm-vips/archive/${VERSION_WASM_VIPS}.tar.gz | tar xzC "${DIR}" --strip-components=1
fi

# Check libvips versions match
VERSION_VIPS_UPSTREAM=$(grep -Po "^VERSION_VIPS=\K[^ ]*" "${DIR}/build.sh")
if [ "$VERSION_VIPS" != "$VERSION_VIPS_UPSTREAM" ]; then
echo "Expected libvips $VERSION_VIPS, found $VERSION_VIPS_UPSTREAM upstream" # TODO: modify build.sh on-the-fly?
exit 1
fi

# Create container with emscripten
if [ -z "$(docker images -q ${TAG})" ]; then
pushd "${DIR}"
docker build -t "${TAG}" .
popd
fi

# Build libvips and dependencies as static Wasm libraries via emscripten
if [ ! -d "$DIR/build/target/lib" ]; then
docker run --rm -v "$PWD/${DIR}":/src "${TAG}" -c "./build.sh --disable-bindings --disable-modules --disable-jxl --enable-libvips-cpp"
fi

# Copy only the files we need
cp -r --no-preserve=mode,ownership ${DIR}/build/target/{include,lib,versions.json} ../npm/dev-wasm32
rm -r ../npm/dev-wasm32/lib/cmake
31 changes: 31 additions & 0 deletions npm/dev-wasm32/THIRD-PARTY-NOTICES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Third-party notices

This software contains third-party libraries
used under the terms of the following licences:

| Library | Used under the terms of |
|---------------|-----------------------------------------------------------------------------------------------------------|
| aom | BSD 2-Clause + [Alliance for Open Media Patent License 1.0](https://aomedia.org/license/patent-license/) |
| cgif | MIT Licence |
| expat | MIT Licence |
| glib | LGPLv3 |
| highway | Apache-2.0 License, BSD 3-Clause |
| lcms | MIT Licence |
| libexif | LGPLv3 |
| libffi | MIT Licence |
| libheif | LGPLv3 |
| libimagequant | [BSD 2-Clause](https://github.com/lovell/libimagequant/blob/main/COPYRIGHT) |
| mozjpeg | [zlib License, IJG License, BSD-3-Clause](https://github.com/mozilla/mozjpeg/blob/master/LICENSE.md) |
| libnsgif | MIT Licence |
| libspng | [BSD 2-Clause, libpng License](https://github.com/randy408/libspng/blob/master/LICENSE) |
| libtiff | [libtiff License](https://gitlab.com/libtiff/libtiff/blob/master/LICENSE.md) (BSD-like) |
| libvips | LGPLv3 |
| libwebp | New BSD License |
| resvg | MPL-2.0 License |
| zlib-ng | [zlib Licence](https://github.com/zlib-ng/zlib-ng/blob/develop/LICENSE.md) |

Use of libraries under the terms of the LGPLv3 is via the
"any later version" clause of the LGPLv2 or LGPLv2.1.

Please report any errors or omissions via
https://github.com/lovell/sharp-libvips/issues/new
31 changes: 31 additions & 0 deletions npm/dev-wasm32/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "@img/sharp-libvips-dev-wasm32",
"version": "0.0.3",
"description": "Header files and static wasm32 libraries for libvips and dependencies to build sharp as wasm32",
"author": "Lovell Fuller <[email protected]>",
"homepage": "https://sharp.pixelplumbing.com",
"repository": {
"type": "git",
"url": "git+https://github.com/lovell/sharp-libvips.git",
"directory": "npm/dev-wasm32"
},
"license": "LGPL-3.0-or-later",
"funding": {
"url": "https://opencollective.com/libvips"
},
"preferUnplugged": true,
"publishConfig": {
"access": "public"
},
"files": [
"include",
"lib",
"versions.json"
],
"type": "commonjs",
"exports": {
"./include": "./include/index.js",
"./lib": "./lib/index.js",
"./versions": "./versions.json"
}
}
1 change: 1 addition & 0 deletions npm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": "true",
"workspaces": [
"dev",
"dev-wasm32",
"darwin-x64",
"darwin-arm64",
"linux-arm",
Expand Down
4 changes: 2 additions & 2 deletions npm/populate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ generate_index() {

remove_unused() {
PACKAGE="$1"
if [ "$PACKAGE" != "dev" ]; then
if [[ "$PACKAGE" != "dev"* ]]; then
rm -r "npm/$PACKAGE/include"
rm "npm/$PACKAGE/THIRD-PARTY-NOTICES.md"
fi
rm "npm/$PACKAGE/THIRD-PARTY-NOTICES.md"
}

# Download and extract per-platform binaries
Expand Down

0 comments on commit f5c3871

Please sign in to comment.