Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting --closure 1 causes JSC_UNDEFINED_VARIABLE errors #21732

Open
oboukli opened this issue Apr 9, 2024 · 3 comments
Open

Setting --closure 1 causes JSC_UNDEFINED_VARIABLE errors #21732

oboukli opened this issue Apr 9, 2024 · 3 comments

Comments

@oboukli
Copy link
Contributor

oboukli commented Apr 9, 2024

Version of emscripten/emsdk:

docker run -it --rm emscripten/emsdk:3.1.56 emcc --version
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.56 (cf90417346b78455089e64eb909d71d091ecc055)

Failing command line in full:

docker run -it --rm \
-v $(pwd):/src \
-v $(pwd)/emscripten_cache:/emsdk/upstream/emscripten/cache \
-v $(pwd)/emscripten_tmp:/tmp \
--workdir=/src emscripten/emsdk:3.1.56 \
emcc \
--closure 1 \
--use-port=sdl2 \
-l EGL \
-l GL \
-l html5 \
-s ASSERTIONS=1 \
-s ASYNCIFY \
-s ERROR_ON_UNDEFINED_SYMBOLS=1 \
-s EXPORTED_FUNCTIONS=_main \
-s FILESYSTEM=0 \
-s NO_EXIT_RUNTIME \
-s STRICT \
-s USE_CLOSURE_COMPILER \
-v \
-o index.html main.c

main.c

// Minimal SDL2 example

#include <emscripten.h>
#include <SDL2/SDL.h>

EMSCRIPTEN_KEEPALIVE int main() {
  SDL_Window* window = SDL_CreateWindow(
    "", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 128, 128, SDL_WINDOW_SHOWN);
  SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
  SDL_SetRenderDrawColor(renderer, 255, 127, 0, 255);
  SDL_RenderClear(renderer);
  SDL_RenderPresent(renderer);
}

Full link command and output with -v appended:

 /emsdk/upstream/bin/clang -target wasm32-unknown-emscripten -fignore-exceptions -fvisibility=default -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=/emsdk/upstream/emscripten/cache/sysroot -Werror=implicit-function-declaration -isystem /emsdk/upstream/emscripten/cache/sysroot/include/SDL2 -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -v main.c -c -o /tmp/emscripten_temp_f3tri3oj/main_0.o
clang version 19.0.0git (https:/github.com/llvm/llvm-project 34ba90745fa55777436a2429a51a3799c83c6d4c)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /emsdk/upstream/bin
 (in-process)
 "/emsdk/upstream/bin/clang-19" -cc1 -triple wasm32-unknown-emscripten -emit-obj -mrelax-all -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.c -mrelocation-model static -mframe-pointer=none -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/src -v -fcoverage-compilation-dir=/src -resource-dir /emsdk/upstream/lib/clang/19 -isystem /emsdk/upstream/emscripten/cache/sysroot/include/SDL2 -isysroot /emsdk/upstream/emscripten/cache/sysroot -internal-isystem /emsdk/upstream/lib/clang/19/include -internal-isystem /emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten -internal-isystem /emsdk/upstream/emscripten/cache/sysroot/include -Werror=implicit-function-declaration -ferror-limit 19 -fvisibility=default -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fignore-exceptions -fcolor-diagnostics -iwithsysroot/include/fakesdl -iwithsysroot/include/compat -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -o /tmp/emscripten_temp_f3tri3oj/main_0.o -x c main.c
clang -cc1 version 19.0.0git based upon LLVM 19.0.0git default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/emsdk/upstream/emscripten/cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
 /emsdk/upstream/emscripten/cache/sysroot/include/SDL2
 /emsdk/upstream/emscripten/cache/sysroot/include/fakesdl
 /emsdk/upstream/emscripten/cache/sysroot/include/compat
 /emsdk/upstream/lib/clang/19/include
 /emsdk/upstream/emscripten/cache/sysroot/include
End of search list.
 /emsdk/upstream/bin/clang --version
 /emsdk/upstream/bin/wasm-ld -o index.wasm -lhtml5 /tmp/emscripten_temp_f3tri3oj/main_0.o -L/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten /emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libSDL2.a --whole-archive -lGL-getprocaddr --no-whole-archive -lnoexit -lc-debug -ldlmalloc -lcompiler_rt -lsockets --fatal-warnings -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmp06pqoks6libemscripten_js_symbols.so --export=emscripten_stack_get_end --export=emscripten_stack_get_free --export=emscripten_stack_get_base --export=emscripten_stack_get_current --export=emscripten_stack_init --export=stackAlloc --export=stackSave --export=stackRestore --export=__get_temp_ret --export=__set_temp_ret --export=__wasm_call_ctors --export=malloc --export=free --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=fflush --export-table -z stack-size=65536 --no-growable-memory --initial-heap=16777216 --no-entry --stack-first --table-base=1
 /emsdk/upstream/bin/llvm-objcopy index.wasm index.wasm --remove-section=.debug* --remove-section=producers
 /emsdk/upstream/bin/wasm-emscripten-finalize --pass-arg=legalize-js-interface-exported-helpers index.wasm -o index.wasm --detect-features
 /emsdk/node/16.20.0_64bit/bin/node /emsdk/upstream/emscripten/src/compiler.mjs /tmp/tmp4e9mvlxh.json
 /emsdk/upstream/bin/wasm-opt --asyncify --pass-arg=asyncify-asserts --pass-arg=asyncify-imports@env.invoke_*,env.__asyncjs__*,*.fd_sync,*.emscripten_promise_await,*.emscripten_sleep,*.emscripten_wget_data,*.emscripten_scan_registers,*.emscripten_lazy_load_code,*._load_secondary_module,*.emscripten_fiber_swap index.wasm -o index.wasm --mvp-features --enable-mutable-globals --enable-sign-ext
 /emsdk/node/16.20.0_64bit/bin/node --max_old_space_size=8192 /emsdk/upstream/emscripten/node_modules/.bin/google-closure-compiler --compilation_level ADVANCED_OPTIMIZATIONS --language_in ECMASCRIPT_2021 --language_out NO_TRANSPILE --emit_use_strict=false --externs /emsdk/upstream/emscripten/src/closure-externs/closure-externs.js --externs /emsdk/upstream/emscripten/src/closure-externs/node-externs.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/buffer.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/string_decoder.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/os.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/tty.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/domain.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/process.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/readline.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/path.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/vm.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/dgram.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/events.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/util.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/dns.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/zlib.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/punycode.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/url.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/cluster.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/stream.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/repl.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/child_process.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/https.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/querystring.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/net.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/tls.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/fs.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/http.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/core.js --externs /emsdk/upstream/emscripten/src/closure-externs/dyncall-externs.js --js /tmp/emscripten_temp_f3tri3oj/index.js --js_output_file tmp2b31moes.cc.js --formatting PRETTY_PRINT
building:ERROR: Closure compiler run failed:

building:ERROR: /tmp/emscripten_temp_f3tri3oj/index.js:1042:183: ERROR - [JSC_UNDEFINED_VARIABLE] variable allocate is undeclared
  1042|  132338: ($0) => { var str = UTF8ToString($0) + '\n\n' + 'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :'; var reply = window.prompt(str, "i"); if (reply === null) { reply = "i"; } return allocate(intArrayFromString(reply), 'i8', ALLOC_NORMAL); },  
                                                                                                                                                                                               ^^^^^^^^

/tmp/emscripten_temp_f3tri3oj/index.js:1042:192: ERROR - [JSC_UNDEFINED_VARIABLE] variable intArrayFromString is undeclared
  1042|  132338: ($0) => { var str = UTF8ToString($0) + '\n\n' + 'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :'; var reply = window.prompt(str, "i"); if (reply === null) { reply = "i"; } return allocate(intArrayFromString(reply), 'i8', ALLOC_NORMAL); },  
                                                                                                                                                                                                        ^^^^^^^^^^^^^^^^^^

/tmp/emscripten_temp_f3tri3oj/index.js:1042:225: ERROR - [JSC_UNDEFINED_VARIABLE] variable ALLOC_NORMAL is undeclared
  1042|  132338: ($0) => { var str = UTF8ToString($0) + '\n\n' + 'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :'; var reply = window.prompt(str, "i"); if (reply === null) { reply = "i"; } return allocate(intArrayFromString(reply), 'i8', ALLOC_NORMAL); },  
                                                                                                                                                                                                                                         ^^^^^^^^^^^^

3 error(s), 0 warning(s)

emcc: error: closure compiler failed (rc: 3): /emsdk/node/16.20.0_64bit/bin/node --max_old_space_size=8192 /emsdk/upstream/emscripten/node_modules/.bin/google-closure-compiler --compilation_level ADVANCED_OPTIMIZATIONS --language_in ECMASCRIPT_2021 --language_out NO_TRANSPILE --emit_use_strict=false --externs /emsdk/upstream/emscripten/src/closure-externs/closure-externs.js --externs /emsdk/upstream/emscripten/src/closure-externs/node-externs.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/buffer.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/string_decoder.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/os.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/tty.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/domain.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/process.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/readline.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/path.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/vm.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/dgram.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/events.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/util.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/dns.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/zlib.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/punycode.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/url.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/cluster.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/stream.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/repl.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/child_process.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/https.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/querystring.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/net.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/tls.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/fs.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/http.js --externs /emsdk/upstream/emscripten/third_party/closure-compiler/node-externs/core.js --externs /emsdk/upstream/emscripten/src/closure-externs/dyncall-externs.js --js /tmp/emscripten_temp_f3tri3oj/index.js --js_output_file tmp2b31moes.cc.js --formatting PRETTY_PRINT

Note that the above builds correctly on emsdk v3.1.47 (using -sUSE_SDL=2 instead of --use-port=sdl2)

@sbc100
Copy link
Collaborator

sbc100 commented Apr 10, 2024

Hmm.. it looks like SDL is using some JS library symbols that are not present by default.

We should fix that upstream in SDL.

In the mean time you can do -sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=allocate,ALLOC_NORMAL,intArrayFromString to include those symbols in your build.

@oboukli
Copy link
Contributor Author

oboukli commented Apr 10, 2024

Tried that and got new errors. BTW, changing FILESYSTEM also changes the error.

Note that in the minimal example above, it seems that, at least since v3.1.56, it's required to add -lEGL -lGL -lhtml5 although I'm not sure the docs mention -lhtml5 explicitly.

I've been unable to build with a similar setup since after v3.1.47 . Perhaps tests with strict and fine-tuned settings could be missing.

@sbc100
Copy link
Collaborator

sbc100 commented Apr 10, 2024

The requirement to explicitly add -lEGL -lGL -lhtml5 is because you are using -sSTRICT, and this sets -sAUTO_JS_LIBRARIES=0 which means you have to explicitly add those libraries, they don't get included automatically.

See https://emscripten.org/docs/tools_reference/settings_reference.html?highlight=environment#strict

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants