mirror of
https://github.com/BinomialLLC/basis_universal.git
synced 2026-10-28 19:55:30 +00:00
Add opt-in WebGL builds that do not use eval()/new Function()
With the default DYNAMIC_EXECUTION=1, embind generates its invokers at runtime with new Function(). A Content-Security-Policy without 'unsafe-eval' blocks this, so the transcoder and encoder fail to start with an EvalError. Add two CMake options to webgl/transcoder and webgl/encoder: - NO_DYNAMIC_EXECUTION (default OFF) adds -s DYNAMIC_EXECUTION=0. - EMBIND_AOT (default ON, only used with NO_DYNAMIC_EXECUTION) adds -s EMBIND_AOT=1. This generates the invokers at build time, so embind calls stay as fast as with the default build. The default build does not change. The .wasm output is byte-identical in all configurations; only the JS glue changes. Fixes #464
This commit is contained in:
+2
-1
@@ -11,6 +11,7 @@
|
||||
# ./build.sh --clean # make clean + wipe CMake cache first (full rebuild)
|
||||
# ./build.sh --slow # serial build (plain make, one file at a time)
|
||||
# ./build.sh encoder -DKTX2_ZSTANDARD=OFF -DCMAKE_BUILD_TYPE=Debug
|
||||
# ./build.sh -DNO_DYNAMIC_EXECUTION=ON # no eval/new Function (strict CSP)
|
||||
#
|
||||
# Any -D... argument is forwarded to cmake. Runnable from any directory.
|
||||
#
|
||||
@@ -35,7 +36,7 @@ for a in "$@"; do
|
||||
--slow) SLOW=1 ;;
|
||||
transcoder|encoder) TARGETS+=("$a") ;;
|
||||
-D*) CMAKE_ARGS+=("$a") ;;
|
||||
-h|--help) sed -n '3,15p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||
-h|--help) sed -n '3,16p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||
*) die "unknown argument: '$a' (try --help)" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
@@ -5,8 +5,18 @@ project(basisu_encoder_js)
|
||||
option(KTX2_ZSTANDARD "Enable KTX2 Zstandard support" TRUE)
|
||||
option(SUPPORT_ASTCENC "Enable astcenc support" FALSE)
|
||||
|
||||
# Build JavaScript glue that never calls eval() or new Function(), so the module
|
||||
# loads under a Content-Security-Policy without 'unsafe-eval' (OFF by default).
|
||||
option(NO_DYNAMIC_EXECUTION "Disallow eval()/new Function() in the JS glue" FALSE)
|
||||
|
||||
# With NO_DYNAMIC_EXECUTION, generate the embind call wrappers at build time (fast)
|
||||
# instead of using the slower generic wrappers. No effect unless NO_DYNAMIC_EXECUTION is ON.
|
||||
option(EMBIND_AOT "Generate embind wrappers at build time" TRUE)
|
||||
|
||||
message("KTX2_ZSTANDARD=${KTX2_ZSTANDARD}")
|
||||
message("SUPPORT_ASTCENC=${SUPPORT_ASTCENC}")
|
||||
message("NO_DYNAMIC_EXECUTION=${NO_DYNAMIC_EXECUTION}")
|
||||
message("EMBIND_AOT=${EMBIND_AOT}")
|
||||
|
||||
# Only for Emscripten builds.
|
||||
if(EMSCRIPTEN)
|
||||
@@ -132,6 +142,13 @@ if(EMSCRIPTEN)
|
||||
|
||||
# Base link flags
|
||||
set(LINK_BASE "--bind -s ALLOW_MEMORY_GROWTH=1 -s INITIAL_MEMORY=134217728 -s STACK_SIZE=2097152 -s MODULARIZE=1 -s EXPORT_NAME=BASIS -s EXPORTED_RUNTIME_METHODS=['HEAP8']")
|
||||
if(NO_DYNAMIC_EXECUTION)
|
||||
set(LINK_BASE "${LINK_BASE} -s DYNAMIC_EXECUTION=0")
|
||||
if(EMBIND_AOT)
|
||||
set(LINK_BASE "${LINK_BASE} -s EMBIND_AOT=1")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(LINK_THREADS "-s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=32 -s ENVIRONMENT=web,worker")
|
||||
set(LINK_WASM64 "-s MEMORY64=1 -sWASM_BIGINT=1 --profiling-funcs")
|
||||
|
||||
|
||||
@@ -5,3 +5,22 @@ cd webgl/encoder/build/
|
||||
emcmake cmake ../
|
||||
make
|
||||
```
|
||||
|
||||
### Strict Content-Security-Policy (no `unsafe-eval`)
|
||||
|
||||
By default, the generated JavaScript glue uses `new Function()` to build its
|
||||
embind bindings at runtime. A Content-Security-Policy without `'unsafe-eval'`
|
||||
blocks this, and module startup fails with an `EvalError`. To build glue that
|
||||
never calls `eval()` or `new Function()`, add `-DNO_DYNAMIC_EXECUTION=ON`:
|
||||
|
||||
```shell
|
||||
emcmake cmake ../ -DNO_DYNAMIC_EXECUTION=ON
|
||||
make
|
||||
```
|
||||
|
||||
This adds `-s DYNAMIC_EXECUTION=0 -s EMBIND_AOT=1` to the link flags. The
|
||||
`.wasm` file does not change. `EMBIND_AOT` generates the bindings at build
|
||||
time, so JavaScript-to-WASM calls stay as fast as in the default build. The
|
||||
page still needs `'wasm-unsafe-eval'` in `script-src` to compile the
|
||||
WebAssembly module. Use `-DEMBIND_AOT=OFF` to get the smaller, generic
|
||||
bindings, which are slower per call.
|
||||
|
||||
@@ -10,8 +10,18 @@ option(KTX2 "KTX2" TRUE)
|
||||
# If you know you'll never be transcoding KTX2 files using this feature you can set KTX2_ZSTANDARD to 0.
|
||||
option(KTX2_ZSTANDARD "KTX2_ZSTANDARD" TRUE)
|
||||
|
||||
# Use "cmake -DNO_DYNAMIC_EXECUTION=TRUE" to build JavaScript glue that never calls eval() or new Function().
|
||||
# This lets the module load under a Content-Security-Policy without 'unsafe-eval'.
|
||||
option(NO_DYNAMIC_EXECUTION "NO_DYNAMIC_EXECUTION" FALSE)
|
||||
|
||||
# With NO_DYNAMIC_EXECUTION, generate the embind call wrappers at build time (fast) instead of
|
||||
# using the slower generic wrappers. Only has an effect when NO_DYNAMIC_EXECUTION is TRUE.
|
||||
option(EMBIND_AOT "EMBIND_AOT" TRUE)
|
||||
|
||||
message("KTX2=${KTX2}")
|
||||
message("KTX2_ZSTANDARD=${KTX2_ZSTANDARD}")
|
||||
message("NO_DYNAMIC_EXECUTION=${NO_DYNAMIC_EXECUTION}")
|
||||
message("EMBIND_AOT=${EMBIND_AOT}")
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
@@ -61,8 +71,17 @@ if (EMSCRIPTEN)
|
||||
|
||||
target_include_directories(basis_transcoder.js PRIVATE ../../transcoder)
|
||||
|
||||
set(TRANSCODER_LINK_FLAGS "--bind -s ALLOW_MEMORY_GROWTH=1 -O3 -s MALLOC=emmalloc -s MODULARIZE=1 -s EXPORT_NAME=BASIS -s ASSERTIONS=0 -s EXPORTED_RUNTIME_METHODS=['HEAP8']")
|
||||
|
||||
if (NO_DYNAMIC_EXECUTION)
|
||||
set(TRANSCODER_LINK_FLAGS "${TRANSCODER_LINK_FLAGS} -s DYNAMIC_EXECUTION=0")
|
||||
if (EMBIND_AOT)
|
||||
set(TRANSCODER_LINK_FLAGS "${TRANSCODER_LINK_FLAGS} -s EMBIND_AOT=1")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set_target_properties(basis_transcoder.js PROPERTIES
|
||||
OUTPUT_NAME "basis_transcoder"
|
||||
SUFFIX ".js"
|
||||
LINK_FLAGS "--bind -s ALLOW_MEMORY_GROWTH=1 -O3 -s MALLOC=emmalloc -s MODULARIZE=1 -s EXPORT_NAME=BASIS -s ASSERTIONS=0 -s EXPORTED_RUNTIME_METHODS=['HEAP8']")
|
||||
LINK_FLAGS "${TRANSCODER_LINK_FLAGS}")
|
||||
endif()
|
||||
|
||||
@@ -7,3 +7,22 @@ cd webgl/transcoder/build/
|
||||
emcmake cmake ../
|
||||
make
|
||||
```
|
||||
|
||||
### Strict Content-Security-Policy (no `unsafe-eval`)
|
||||
|
||||
By default, the generated JavaScript glue uses `new Function()` to build its
|
||||
embind bindings at runtime. A Content-Security-Policy without `'unsafe-eval'`
|
||||
blocks this, and module startup fails with an `EvalError`. To build glue that
|
||||
never calls `eval()` or `new Function()`, add `-DNO_DYNAMIC_EXECUTION=ON`:
|
||||
|
||||
```shell
|
||||
emcmake cmake ../ -DNO_DYNAMIC_EXECUTION=ON
|
||||
make
|
||||
```
|
||||
|
||||
This adds `-s DYNAMIC_EXECUTION=0 -s EMBIND_AOT=1` to the link flags. The
|
||||
`.wasm` file does not change. `EMBIND_AOT` generates the bindings at build
|
||||
time, so JavaScript-to-WASM calls stay as fast as in the default build. The
|
||||
page still needs `'wasm-unsafe-eval'` in `script-src` to compile the
|
||||
WebAssembly module. Use `-DEMBIND_AOT=OFF` to get the smaller, generic
|
||||
bindings, which are slower per call.
|
||||
|
||||
Reference in New Issue
Block a user