summaryrefslogtreecommitdiffstats
path: root/build
diff options
context:
space:
mode:
Diffstat (limited to 'build')
-rw-r--r--build/Dockerfile18
-rw-r--r--build/wasm.js101
2 files changed, 119 insertions, 0 deletions
diff --git a/build/Dockerfile b/build/Dockerfile
new file mode 100644
index 0000000..5438b73
--- /dev/null
+++ b/build/Dockerfile
@@ -0,0 +1,18 @@
+FROM node:20-alpine@sha256:4559bc033338938e54d0a3c2f0d7c3ad7d1d13c28c4c405b85c6b3a26f4ce5f7
+
+ARG UID=1000
+ARG GID=1000
+
+RUN apk add -U clang lld wasi-sdk
+RUN mkdir /home/node/undici
+
+WORKDIR /home/node/undici
+
+COPY package.json .
+COPY build build
+COPY deps deps
+COPY lib lib
+
+RUN npm i
+
+USER node
diff --git a/build/wasm.js b/build/wasm.js
new file mode 100644
index 0000000..fd90ac2
--- /dev/null
+++ b/build/wasm.js
@@ -0,0 +1,101 @@
+'use strict'
+
+const { execSync } = require('child_process')
+const { writeFileSync, readFileSync } = require('fs')
+const { join, resolve } = require('path')
+
+const ROOT = resolve(__dirname, '../')
+const WASM_SRC = resolve(__dirname, '../deps/llhttp')
+const WASM_OUT = resolve(__dirname, '../lib/llhttp')
+const DOCKERFILE = resolve(__dirname, './Dockerfile')
+
+let platform = process.env.WASM_PLATFORM
+if (!platform && process.argv[2]) {
+ platform = execSync('docker info -f "{{.OSType}}/{{.Architecture}}"').toString().trim()
+}
+
+if (process.argv[2] === '--prebuild') {
+ const cmd = `docker build --platform=${platform.toString().trim()} -t llhttp_wasm_builder -f ${DOCKERFILE} ${ROOT}`
+
+ console.log(`> ${cmd}\n\n`)
+ execSync(cmd, { stdio: 'inherit' })
+
+ process.exit(0)
+}
+
+if (process.argv[2] === '--docker') {
+ let cmd = `docker run --rm -it --platform=${platform.toString().trim()}`
+ if (process.platform === 'linux') {
+ cmd += ` --user ${process.getuid()}:${process.getegid()}`
+ }
+
+ cmd += ` --mount type=bind,source=${ROOT}/lib/llhttp,target=/home/node/undici/lib/llhttp llhttp_wasm_builder node build/wasm.js`
+ console.log(`> ${cmd}\n\n`)
+ execSync(cmd, { stdio: 'inherit' })
+ process.exit(0)
+}
+
+// Gather information about the tools used for the build
+const buildInfo = execSync('apk info -v').toString()
+if (!buildInfo.includes('wasi-sdk')) {
+ console.log('Failed to generate build environment information')
+ process.exit(-1)
+}
+writeFileSync(join(WASM_OUT, 'wasm_build_env.txt'), buildInfo)
+
+// Build wasm binary
+execSync(`clang \
+ --sysroot=/usr/share/wasi-sysroot \
+ -target wasm32-unknown-wasi \
+ -Ofast \
+ -fno-exceptions \
+ -fvisibility=hidden \
+ -mexec-model=reactor \
+ -Wl,-error-limit=0 \
+ -Wl,-O3 \
+ -Wl,--lto-O3 \
+ -Wl,--strip-all \
+ -Wl,--allow-undefined \
+ -Wl,--export-dynamic \
+ -Wl,--export-table \
+ -Wl,--export=malloc \
+ -Wl,--export=free \
+ -Wl,--no-entry \
+ ${join(WASM_SRC, 'src')}/*.c \
+ -I${join(WASM_SRC, 'include')} \
+ -o ${join(WASM_OUT, 'llhttp.wasm')}`, { stdio: 'inherit' })
+
+const base64Wasm = readFileSync(join(WASM_OUT, 'llhttp.wasm')).toString('base64')
+writeFileSync(
+ join(WASM_OUT, 'llhttp-wasm.js'),
+ `module.exports = '${base64Wasm}'\n`
+)
+
+// Build wasm simd binary
+execSync(`clang \
+ --sysroot=/usr/share/wasi-sysroot \
+ -target wasm32-unknown-wasi \
+ -msimd128 \
+ -Ofast \
+ -fno-exceptions \
+ -fvisibility=hidden \
+ -mexec-model=reactor \
+ -Wl,-error-limit=0 \
+ -Wl,-O3 \
+ -Wl,--lto-O3 \
+ -Wl,--strip-all \
+ -Wl,--allow-undefined \
+ -Wl,--export-dynamic \
+ -Wl,--export-table \
+ -Wl,--export=malloc \
+ -Wl,--export=free \
+ -Wl,--no-entry \
+ ${join(WASM_SRC, 'src')}/*.c \
+ -I${join(WASM_SRC, 'include')} \
+ -o ${join(WASM_OUT, 'llhttp_simd.wasm')}`, { stdio: 'inherit' })
+
+const base64WasmSimd = readFileSync(join(WASM_OUT, 'llhttp_simd.wasm')).toString('base64')
+writeFileSync(
+ join(WASM_OUT, 'llhttp_simd-wasm.js'),
+ `module.exports = '${base64WasmSimd}'\n`
+)