diff --git a/.gitlab/ci/docker/Dockerfile b/.gitlab/ci/docker/Dockerfile index 6e4a358e472b2d2def7a9f7f317ab16b59483103..4f82a49461eacf017fceb0715213f3e23b6f86e1 100644 --- a/.gitlab/ci/docker/Dockerfile +++ b/.gitlab/ci/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/dockcross/web-wasm:20240812-60fa1b0 +FROM emscripten/emsdk:4.0.3 LABEL maintainer="Jaswant Panchumarti jaswant.panchumarti@kitware.com" ARG BUILD_DATE @@ -11,37 +11,60 @@ ARG VENDOR="Kitware Inc." # VTK version: preferably $(git describe) from VTK source repo ARG VERSION +# Needed to install build tools +ARG CMAKE_CONFIGURATION # Forwarded to VTK_WEBASSEMBLY_64_BIT ARG ENABLE_64_BIT=OFF # Forwarded to VTK_WEBASSEMBLY_THREADS ARG ENABLE_THREADS=OFF +# Fetch node v8 canary binary +RUN wget https://nodejs.org/download/v8-canary/v24.0.0-v8-canary2025030537242e55ac/node-v24.0.0-v8-canary2025030537242e55ac-linux-x64.tar.gz && \ + echo "e1b375e5ee9ebed682a5bbb94a26c009b5be88205d0fca7ed8b8acc99d315724 node-v24.0.0-v8-canary2025030537242e55ac-linux-x64.tar.gz" > node.sha256sum && \ + sha256sum -c node.sha256sum && \ + tar -xvzf ./node-v24.0.0-v8-canary2025030537242e55ac-linux-x64.tar.gz && \ + mv -v ./node-v24.0.0-v8-canary2025030537242e55ac-linux-x64 "/opt/node" +# For consumers of this image to find and use the correct node. +ENV PATH="/opt/node/bin:$PATH" +ENV NODE_DIR="/opt/node" + RUN cmake --version && \ - ninja --version && \ emcc --version && \ + apt update && \ + apt install -y ninja-build && \ + ninja --version && \ + export CMAKE_CONFIGURATION=${CMAKE_CONFIGURATION} && \ cd /VTK-src/ && \ - CMAKE_CONFIGURATION="linux" cmake -P ".gitlab/ci/download_node.cmake" && \ - export PATH=$PWD/.gitlab:$PWD/.gitlab/node/bin:$PATH && \ - export NODE_DIR=$PWD/.gitlab/node && \ + # Fetch node + # node with v8 < 13.2 is incapable of executing wasm64 binaries generated by emsdk 4.0.3 + # Disabling until node v24 is out, see https://github.com/nodejs/node/issues/57057 + # cmake -P ".gitlab/ci/download_node.cmake" && \ + # export NODE_DIR="$PWD/.gitlab/node" && \ + # export PATH="$PWD/.gitlab/node/bin:$PATH" && \ node --version && \ - export SCCACHE_MOUNTPOINT=$PWD/.gitlab/sccache && \ - $SCCACHE_MOUNTPOINT --start-server && $SCCACHE_MOUNTPOINT --show-stats && \ + # Fetch dawn + cmake -P ".gitlab/ci/download_dawn.cmake" && \ + export SCCACHE_MOUNTPOINT="$PWD/.gitlab/sccache" && \ + $SCCACHE_MOUNTPOINT --start-server && \ cmake \ - -DCMAKE_CROSSCOMPILING_EMULATOR=$PWD/.gitlab/node/bin/node \ - -DCMAKE_C_COMPILER_LAUNCHER=$SCCACHE_MOUNTPOINT \ - -DCMAKE_CXX_COMPILER_LAUNCHER=$SCCACHE_MOUNTPOINT \ + -DCMAKE_TOOLCHAIN_FILE:FILEPATH="${EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake" \ + -DCMAKE_CROSSCOMPILING_EMULATOR="$PWD/.gitlab/node/bin/node" \ + -DCMAKE_C_COMPILER_LAUNCHER="$SCCACHE_MOUNTPOINT" \ + -DCMAKE_CXX_COMPILER_LAUNCHER="$SCCACHE_MOUNTPOINT" \ -DCMAKE_C_FLAGS=-Wno-limited-postlink-optimizations \ -DCMAKE_CXX_FLAGS=-Wno-limited-postlink-optimizations \ -DCMAKE_EXE_LINKER_FLAGS=-Wno-limited-postlink-optimizations \ - -S $PWD \ + -S "$PWD" \ -B /VTK-build \ -G "Ninja Multi-Config" \ + -Demdawnwebgpu_DIR="$PWD/.gitlab/dawn//lib/cmake/emdawnwebgpu" \ -DVTK_WEBASSEMBLY_64_BIT=${ENABLE_64_BIT} \ -DVTK_WEBASSEMBLY_THREADS=${ENABLE_THREADS} \ -DBUILD_SHARED_LIBS:BOOL=OFF \ - -DVTK_ENABLE_LOGGING:BOOL=OFF \ + -DVTK_ENABLE_LOGGING:BOOL=ON \ -DVTK_ENABLE_WEBGPU:BOOL=ON \ -DVTK_ENABLE_WRAPPING:BOOL=OFF \ + -DVTK_MODULE_ENABLE_VTK_sqlite:STRING=NO \ -DVTK_MODULE_ENABLE_VTK_RenderingLICOpenGL2:STRING=DONT_WANT \ -DVTK_VERSIONED_INSTALL=OFF && \ cmake --build /VTK-build --config "Release" && \ @@ -49,11 +72,7 @@ RUN cmake --version && \ cmake --build /VTK-build --config "Debug" && \ cmake --install /VTK-build --config "Debug" --prefix /VTK-install/Debug && \ $SCCACHE_MOUNTPOINT --show-stats && \ - rm -rf /VTK-build && \ - chmod -R 777 /emsdk/upstream/emscripten/cache - -ENV DEFAULT_DOCKCROSS_IMAGE=${IMAGE_NAME}:${IMAGE_TAG} -COPY web-build /usr/local/bin/ + rm -rf /VTK-build # Build-time metadata as defined at https://github.com/opencontainers/image-spec/blob/main/annotations.md LABEL org.opencontainers.image.created=${BUILD_DATE} \ diff --git a/.gitlab/ci/docker/build.sh b/.gitlab/ci/docker/build.sh index ba69ac6d2ad74c2919ec4c4781518daa4b4fc343..e4c4912bf0785ec4416d2a7521e39bbc581e781c 100755 --- a/.gitlab/ci/docker/build.sh +++ b/.gitlab/ci/docker/build.sh @@ -26,18 +26,22 @@ readonly vtk_vcs_url # Parse build architecture. case "$VTK_BUILD_ARCHITECTURE" in wasm32) + cmake_configuration=wasm32_emscripten_linux enable_64_bit=OFF enable_threads=OFF ;; wasm32-threads) + cmake_configuration=wasm32_emscripten_linux enable_64_bit=OFF enable_threads=ON ;; wasm64) + cmake_configuration=wasm64_emscripten_linux enable_64_bit=ON enable_threads=OFF ;; wasm64-threads) + cmake_configuration=wasm64_emscripten_linux enable_64_bit=ON enable_threads=ON ;; @@ -46,6 +50,7 @@ case "$VTK_BUILD_ARCHITECTURE" in exit 1 ;; esac +readonly cmake_configuration readonly enable_64_bit readonly enable_threads @@ -66,7 +71,6 @@ vtk_version="$(git describe)" readonly vtk_version # Setup sccache. .gitlab/ci/sccache.sh -# Do not need to install cmake and ninja because the dockcross/web-wasm image already has those two. cd "$current_dir" # Use podman to avoid having to do docker-in-docker shenanigans. @@ -93,6 +97,7 @@ $docker build --format=docker \ "--build-arg=REVISION=$vtk_vcs_ref" \ "--build-arg=SOURCE_URL=$vtk_vcs_url" \ "--build-arg=VERSION=$vtk_version" \ + "--build-arg=CMAKE_CONFIGURATION=$cmake_configuration" \ "--build-arg=ENABLE_64_BIT=$enable_64_bit" \ "--build-arg=ENABLE_THREADS=$enable_threads" \ -t "kitware/vtk-wasm-sdk:$image_tag" \ diff --git a/.gitlab/ci/docker/tests/basic/CMakeLists.txt b/.gitlab/ci/docker/tests/basic/CMakeLists.txt index ced501cfe6d0d30b9dc3f1c3b4bcf30d66e37c8f..c7e73f8285b1d7d4088da8e19ddfa73b7a47d973 100644 --- a/.gitlab/ci/docker/tests/basic/CMakeLists.txt +++ b/.gitlab/ci/docker/tests/basic/CMakeLists.txt @@ -20,19 +20,14 @@ vtk_module_autoinit( TARGETS main MODULES ${VTK_LIBRARIES}) -# Download nodejs -execute_process( - COMMAND "${CMAKE_COMMAND}" "-P" "${CMAKE_CURRENT_LIST_DIR}/download_node.cmake" - WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}") - if (${CMAKE_SIZEOF_VOID_P} EQUAL 8) add_test( NAME "basic-wasm64-test" - COMMAND "${CMAKE_CURRENT_LIST_DIR}/node/bin/node" "--experimental-wasm-memory64" "$" "64" "0") + COMMAND "node" "$" "64" "0") else () add_test( NAME "basic-wasm32-test" - COMMAND "${CMAKE_CURRENT_LIST_DIR}/node/bin/node" "$" "32" "0") + COMMAND "node" "$" "32" "0") endif () if (ENABLE_THREADS) @@ -40,10 +35,10 @@ if (ENABLE_THREADS) if (${CMAKE_SIZEOF_VOID_P} EQUAL 8) add_test( NAME "basic-wasm64-threads" - COMMAND "${CMAKE_CURRENT_LIST_DIR}/node/bin/node" "--experimental-wasm-memory64" "$" "64" "${num_threads}") + COMMAND "node" "$" "64" "${num_threads}") else () add_test( NAME "basic-wasm32-threads" - COMMAND "${CMAKE_CURRENT_LIST_DIR}/node/bin/node" "$" "32" "${num_threads}") + COMMAND "node" "$" "32" "${num_threads}") endif () endif () diff --git a/.gitlab/ci/docker/tests/basic/download_node.cmake b/.gitlab/ci/docker/tests/basic/download_node.cmake deleted file mode 100644 index 0b6a3afb93e2cdca58050d843292c0fa2eae7f0d..0000000000000000000000000000000000000000 --- a/.gitlab/ci/docker/tests/basic/download_node.cmake +++ /dev/null @@ -1,54 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -set(node_version "22.0.0") -set(node_baseurl "https://nodejs.org/download/release") - -if (${CMAKE_HOST_SYSTEM_NAME} MATCHES "Windows") - set(node_platform "win-x64") - set(node_ext "zip") - set(node_hash "32d639b47d4c0a651ff8f8d7d41a454168a3d4045be37985f9a810cf8cef6174") -elseif (${CMAKE_HOST_SYSTEM_NAME} MATCHES "Linux") - set(node_platform "linux-x64") - set(node_ext "tar.gz") - set(node_hash "74bb0f3a80307c529421c3ed84517b8f543867709f41e53cd73df99e6442af4d") -else () - message(FATAL_ERROR - "Unknown platform for node ${CMAKE_HOST_SYSTEM_NAME}") -endif () -set(node_url "${node_baseurl}/v${node_version}") -set(node_file "node-v${node_version}-${node_platform}.${node_ext}") - -# Download the file. -file(DOWNLOAD - "${node_url}/${node_file}" - "${node_file}" - STATUS download_status - EXPECTED_HASH "SHA256=${node_hash}") - -# Check the download status. -list(GET download_status 0 res) -if (res) - list(GET download_status 1 err) - message(FATAL_ERROR - "Failed to download ${node_file}: ${err}") -endif () - -# Extract the file. -execute_process( - COMMAND - "${CMAKE_COMMAND}" - -E tar - xf "${node_file}" - WORKING_DIRECTORY "." - RESULT_VARIABLE res - ERROR_VARIABLE err - ERROR_STRIP_TRAILING_WHITESPACE) -if (res) - message(FATAL_ERROR - "Failed to extract ${node_file}: ${err}") -endif () - -# Move to a predictable prefix. -file(RENAME - "./node-v${node_version}-${node_platform}" - "./node") diff --git a/.gitlab/ci/docker/web-build b/.gitlab/ci/docker/web-build deleted file mode 100755 index 06d5faf90e9d94facbc88f7272483d5aabb0985c..0000000000000000000000000000000000000000 --- a/.gitlab/ci/docker/web-build +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -# -# Configure and build the CMake project with source code in the current -# directory and build output in "$1". Build configuration is "$2" -# -# Any extra arguments passed to the script and passed to the cmake -# configuration step. -# - -# Get build directory -readonly build_dir=$1 -shift - -# Get the build configuration. The value defaults to "Release" -if [ "$1" ]; then - build_config=$1 - shift -else - build_config="Release" -fi -readonly build_config - -cmake \ - --no-warn-unused-cli \ - -B$build_dir \ - -H. \ - -DCMAKE_BUILD_TYPE:STRING="$build_config" \ - -DVTK_DIR:PATH="/VTK-install/$build_config/lib/cmake/vtk" \ - -GNinja \ - "$@" && \ -cmake --build $build_dir diff --git a/README.md b/README.md index a4160f95cc67577e494912c46b31c4c7de6fa182..e073ffb6f362ef1256a9b032f4befe95b80ac81b 100644 --- a/README.md +++ b/README.md @@ -105,92 +105,3 @@ docker tag kitware/vtk-wasm-sdk:v9.3.0 kitware/vtk-wasm-sdk:latest docker push kitware/vtk-wasm-sdk:latest ``` -## Extending - -If your project uses packages that this image doesn't provide you might want to: - -- Contribute to this repo: Maybe your dependency is either non-intrusive or could be useful for other people -- Create custom image that bases on this image - 1. create own Dockerfile that holds: - - ```Dockerfile - # Point at any base image that you find suitable to extend. - FROM kitware/vtk-wasm-sdk:v9.3.0 - - # Install required tools that are useful for your project i.e. ninja-build - RUN apt update && apt install -y gfortran - ``` - 2. build it - - ```shell - docker build -t extended_vtk_wasm_sdk . - ``` - - 3. test - - ```shell - docker run --rm extended_vtk_wasm_sdk gfortran --version - # GNU Fortran (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4. - ``` - -## Advanced usage (webpack integration) - -In this guide, let's go through steps to integrate VTK-wasm with WebPack and npm scripts. Here's what the directory structure can look like: - -```bash -src -|-App.cpp # C++ code for VTK-wasm application -|-App.h # C++ code for VTK-wasm application (does not expose VTK objects) -|-main.cpp # Optional, no wasm, runs the application natively. -|-CMakeLists.txt # Logic to build App, knows nothing about web/ -web -|-index.html -|-index.js # Initialize wasm module, loads App from C++ land, does web stuff -package.json # Metadata and script hooks to build the project for web. -webpack.config.js # Logic to build and serve webpage -``` - -First, install [itk-wasm](https://wasm.itk.org) and save it in `package.json` -``` -$ npm install --save-dev itk-wasm@1.0.0-b.83 -``` - -Now, let's teach `package.json` the way to build our C++ code with [kitware/vtk-wasm-sdk](https://hub.docker.com/r/kitware/vtk-wasm-sdk) and [itk-wasm](https://wasm.itk.org) CLI. - -```json -"name": ... -"version": ... -"description": ... -"main": "index.js" -"scripts": { - "build-wasm": "npm run build-wasm:release", - "build-wasm:release": "npx itk-wasm -i kitware/vtk-wasm-sdk -b build-emscripten -s src build -- Release -DDEBUGINFO=NONE", - "build-wasm:profile": "npx itk-wasm -i kitware/vtk-wasm-sdk -b build-emscripten -s src build -- Release -DDEBUGINFO=PROFILE", - "build-wasm:debug": "npx itk-wasm -i kitware/vtk-wasm-sdk -b build-emscripten -s src build -- Debug -DDEBUGINFO=DEBUG_NATIVE -DOPTIMIZE=NO_OPTIMIZATION", -} -``` - -After the C++ code is built, the `*.wasm` and `*.js` glue code sit in `src/build-emscripten`. Let's teach `webpack.config.js` to bundle and serve these files along with contents from `web/`. - -```js -plugins: [ - new CopyPlugin({ - patterns: [ - { - from: path.join( - __dirname, "src", "build-emscripten", "NameOfYourWasmApp.js" - ), - to: path.join(__dirname, "dist", "NameOfYourWasmApp.js") - }, - { - from: path.join( - __dirname, "src", "build-emscripten", "NameOfYourWasmApp.wasm" - ), - to: path.join(__dirname, "dist", "NameOfYourWasmApp.wasm") - } - ], - }) -] -``` - -[vtkWasmBenchmark](https://github.com/jspanchu/vtkWasmBenchmark) is a complete example of webpack integration with [kitware/vtk-wasm-sdk](https://hub.docker.com/r/kitware/vtk-wasm-sdk) and [itk-wasm](https://wasm.itk.org) CLI.