From 87e22af95ac4c011185dee3377de949d11859ca6 Mon Sep 17 00:00:00 2001 From: Malcolm Christie Date: Tue, 2 Jun 2026 15:23:10 +0100 Subject: [PATCH] Add V8Js extension layer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduces a Bref Lambda layer for the v8js PECL extension, building V8 12.0.267.36 from source and bundling runtime libraries for PHP 8.2–8.4. Co-authored-by: Cursor --- Readme.md | 1 + layers/v8js/Dockerfile | 66 +++++++++++++++++++++++++++++++++++++++++ layers/v8js/Readme.md | 18 +++++++++++ layers/v8js/config.json | 7 +++++ layers/v8js/test.php | 20 +++++++++++++ 5 files changed, 112 insertions(+) create mode 100644 layers/v8js/Dockerfile create mode 100644 layers/v8js/Readme.md create mode 100644 layers/v8js/config.json create mode 100644 layers/v8js/test.php diff --git a/Readme.md b/Readme.md index ea65f272..2385b5bc 100644 --- a/Readme.md +++ b/Readme.md @@ -100,6 +100,7 @@ functions: | Tideways | `${bref-extra:tideways-php-81}` | | Tidy | `${bref-extra:tidy-php-81}` | | UUID | `${bref-extra:uuid-php-81}` | +| V8Js | `${bref-extra:v8js-php-81}` | | Xdebug | `${bref-extra:xdebug-php-81}` | | Xlswriter | `${bref-extra:xlswriter-php-81}` | | xmlrpc | `${bref-extra:xmlrpc-php-81}` | diff --git a/layers/v8js/Dockerfile b/layers/v8js/Dockerfile new file mode 100644 index 00000000..bd514b12 --- /dev/null +++ b/layers/v8js/Dockerfile @@ -0,0 +1,66 @@ +ARG PHP_VERSION +ARG BREF_VERSION +FROM bref/build-php-$PHP_VERSION:$BREF_VERSION AS ext + +ENV V8JS_BUILD_DIR=${BUILD_DIR}/v8js +ENV V8_VERSION=12.0.267.36 +ENV V8JS_COMMIT=8a39efa3cf3b275e402ddf3c4f6b611a5f69a499 +ENV V8_DIR=${INSTALL_DIR}/v8 + +RUN mkdir -p ${V8JS_BUILD_DIR} +WORKDIR ${V8JS_BUILD_DIR} + +RUN LD_LIBRARY_PATH= dnf -y install \ + gcc \ + gcc-c++ \ + git \ + glib2-devel \ + make \ + ninja-build \ + patchelf \ + pkgconf-pkg-config \ + python3 \ + which + +RUN git clone --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git ${V8JS_BUILD_DIR}/depot_tools +ENV PATH="${V8JS_BUILD_DIR}/depot_tools:${PATH}" +ENV DEPOT_TOOLS_UPDATE=0 + +RUN fetch v8 +WORKDIR ${V8JS_BUILD_DIR}/v8 +RUN git checkout ${V8_VERSION} && gclient sync -D +RUN tools/dev/v8gen.py -vv x64.release -- is_component_build=true use_custom_libcxx=false +RUN ninja -C out.gn/x64.release/ + +RUN mkdir -p ${V8_DIR}/lib ${V8_DIR}/include && \ + cp out.gn/x64.release/lib*.so out.gn/x64.release/*_blob.bin out.gn/x64.release/icudtl.dat ${V8_DIR}/lib/ && \ + cp -R include/* ${V8_DIR}/include/ && \ + for f in ${V8_DIR}/lib/*.so; do patchelf --set-rpath '$ORIGIN' "$f"; done + +WORKDIR ${V8JS_BUILD_DIR} +RUN curl -Ls https://github.com/phpv8/v8js/archive/${V8JS_COMMIT}.tar.gz | tar xz +WORKDIR ${V8JS_BUILD_DIR}/v8js-${V8JS_COMMIT} +RUN phpize && \ + ./configure \ + --with-v8js=${V8_DIR} \ + LDFLAGS="-lstdc++ -Wl,-rpath,${V8_DIR}/lib" \ + CPPFLAGS="-DV8_COMPRESS_POINTERS -DV8_ENABLE_SANDBOX" && \ + make -j "$(nproc)" && \ + make install + +RUN cp "$(php-config --extension-dir)"/v8js.so /tmp/v8js.so +RUN strip --strip-debug /tmp/v8js.so +RUN echo 'extension=v8js.so' > /tmp/ext.ini + +RUN php /bref/lib-copy/copy-dependencies.php /tmp/v8js.so /tmp/extension-libs +RUN cp ${V8_DIR}/lib/libv8*.so ${V8_DIR}/lib/icudtl.dat ${V8_DIR}/lib/*_blob.bin /tmp/extension-libs/ +RUN cp -L /lib64/libstdc++.so.6 /lib64/libgcc_s.so.1 /tmp/extension-libs/ +RUN patchelf --set-rpath '$ORIGIN/../../lib' /tmp/v8js.so +RUN for f in /tmp/extension-libs/*.so; do patchelf --set-rpath '$ORIGIN' "$f"; done + +FROM scratch + +COPY --from=ext /tmp/v8js.so /opt/bref/extensions/v8js.so +COPY --from=ext /tmp/ext.ini /opt/bref/etc/php/conf.d/ext-v8js.ini +COPY --from=ext /opt/v8 /opt/v8 +COPY --from=ext /tmp/extension-libs /opt/lib diff --git a/layers/v8js/Readme.md b/layers/v8js/Readme.md new file mode 100644 index 00000000..bfcede6f --- /dev/null +++ b/layers/v8js/Readme.md @@ -0,0 +1,18 @@ +# V8Js + +PHP bindings for the [V8 JavaScript engine](https://v8.dev/), via [phpv8/v8js](https://github.com/phpv8/v8js). + +## Build notes + +This layer compiles V8 from source during the Docker build. Expect **long CI runtimes** (often 1–3 hours per PHP version) and a **large layer** (V8 shared libraries and ICU data). + +Pinned versions: + +- V8: `12.0.267.36` +- v8js: commit `8a39efa3cf3b275e402ddf3c4f6b611a5f69a499` + +The extension is built with `V8_COMPRESS_POINTERS` and `V8_ENABLE_SANDBOX` to match the V8 build configuration. + +## Lambda limits + +Check the unzipped layer size against the [Lambda deployment package limit](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html) (250 MB unzipped for direct uploads). This layer is significantly larger than typical PECL extensions. diff --git a/layers/v8js/config.json b/layers/v8js/config.json new file mode 100644 index 00000000..2bf25de7 --- /dev/null +++ b/layers/v8js/config.json @@ -0,0 +1,7 @@ +{ + "php": [ + "82", + "83", + "84" + ] +} diff --git a/layers/v8js/test.php b/layers/v8js/test.php new file mode 100644 index 00000000..9146f65f --- /dev/null +++ b/layers/v8js/test.php @@ -0,0 +1,20 @@ +executeString('1 + 1'); +if ($result !== 2) { + echo sprintf('FAIL: Expected 2, got %s.', var_export($result, true)).PHP_EOL; + exit(1); +} + +exit(0);