floooh / cimgui-sokol-starterkit

A minimal self-contained Dear ImGui starter project for Windows, Linux and macOS.
MIT License
221 stars 22 forks source link

Emscripten build fails "ERROR - [JSC_UNDEFINED_VARIABLE] variable ccall is undeclared" #11

Closed Sakari369 closed 1 year ago

Sakari369 commented 1 year ago

Building the project with

emcmake cmake -DCMAKE_BUILD_TYPE=MinSizeRel ..

Fails currently with the message:

configure: cmake -DCMAKE_BUILD_TYPE=MinSizeRel .. -DCMAKE_TOOLCHAIN_FILE=/opt/homebrew/Cellar/emscripten/3.1.24/libexec/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR=/opt/homebrew/opt/node/bin/node;--experimental-wasm-threads
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/cimgui-sokol-starterkit/build
sakari@Viper /tmp/cimgui-sokol-starterkit/build (main)> cmake --build .
[  9%] Building CXX object CMakeFiles/cimgui.dir/cimgui/cimgui.cpp.o
[ 18%] Building CXX object CMakeFiles/cimgui.dir/cimgui/imgui/imgui.cpp.o
[ 27%] Building CXX object CMakeFiles/cimgui.dir/cimgui/imgui/imgui_widgets.cpp.o
[ 36%] Building CXX object CMakeFiles/cimgui.dir/cimgui/imgui/imgui_draw.cpp.o
[ 45%] Building CXX object CMakeFiles/cimgui.dir/cimgui/imgui/imgui_tables.cpp.o
[ 54%] Building CXX object CMakeFiles/cimgui.dir/cimgui/imgui/imgui_demo.cpp.o
[ 63%] Linking CXX static library libcimgui.a
[ 63%] Built target cimgui
[ 72%] Building C object CMakeFiles/sokol.dir/sokol/sokol.c.o
[ 81%] Linking CXX static library libsokol.a
[ 81%] Built target sokol
[ 90%] Building C object CMakeFiles/demo.dir/demo.c.o
[100%] Linking C executable demo.html
building:ERROR: Closure compiler run failed:

building:ERROR: /var/folders/ql/lcdkc34x02z645rm54kwhfb40000gn/T/emscripten_temp_h4fjwxem/demo.jso4.js:562:2: ERROR - [JSC_UNDEFINED_VARIABLE] variable ccall is undeclared
  562|   ccall("_sapp_emsc_onpaste", "void", [ "string" ], [ pasted_str ]);
         ^^^^^

1 error(s), 0 warning(s)

emcc: error: closure compiler failed (rc: 1): /opt/homebrew/opt/node/bin/node --max_old_space_size=8192 /opt/homebrew/Cellar/emscripten/3.1.24/libexec/node_modules/.bin/google-closure-compiler --compilation_level ADVANCED_OPTIMIZATIONS --language_in ECMASCRIPT_2020 --language_out NO_TRANSPILE --emit_use_strict=false --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/src/closure-externs/closure-externs.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/src/closure-externs/node-externs.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/net.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/events.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/repl.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/util.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/dgram.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/vm.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/stream.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/child_process.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/assert.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/core.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/os.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/readline.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/punycode.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/https.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/domain.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/dns.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/tty.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/querystring.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/path.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/string_decoder.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/cluster.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/zlib.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/url.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/tls.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/process.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/http.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/buffer.js --externs /opt/homebrew/Cellar/emscripten/3.1.24/libexec/third_party/closure-compiler/node-externs/fs.js --js /var/folders/ql/lcdkc34x02z645rm54kwhfb40000gn/T/emscripten_temp_h4fjwxem/demo.jso4.js --js_output_file tmpxvagqmwj.cc.js the error message may be clearer with -g1 and EMCC_DEBUG=2 set
make[2]: *** [demo.html] Error 1
make[1]: *** [CMakeFiles/demo.dir/all] Error 2
make: *** [all] Error 2

Running macOS Ventura 13.0 with Emscripten stable 3.1.24.

Probably fails as there were some recent changes in Emscripten and ccall.

Sakari369 commented 1 year ago

Adding the following definition -sLEGACY_RUNTIME=1 into CMakeLists.txt fixes the linking:

# Emscripten-specific linker options
if (CMAKE_SYSTEM_NAME STREQUAL Emscripten)
    set(CMAKE_EXECUTABLE_SUFFIX ".html")
    # use our own minimal shell.html
    target_link_options(demo PRIVATE --shell-file ../sokol/shell.html)
    # WASM+JS size optimizations
    target_link_options(demo PRIVATE -sLEGACY_RUNTIME=1 -sNO_FILESYSTEM=1 -sASSERTIONS=0 -sMALLOC=emmalloc --closure=1)
endif()

As mentioned by Emscripten ChangeLog (https://github.com/emscripten-core/emscripten/blob/main/ChangeLog.md):

The LEGACY_RUNTIME setting is no longer enabled by default. If you use any of these legacy runtime functions (except in library code with explicit dependencies) then you would need to set LEGACY_RUNTIME on the command line or add the ones you need to DEFAULT_LIBRARY_FUNCS_TO_INCLUDE:
floooh commented 1 year ago

Ah yes, this was a quite recent Emscripten change. I had fixed this in the sokol headers using a new Emscripten feature (EM_JS_DEPS macro), but haven't updated the sokol headers everywhere yet. I just did this, so it should be fixed now (tested on my machine with emsdk 3.1.24 (you need this latest version because of EM_JS_DEPS).

Sakari369 commented 1 year ago

Nice! And continue the good work, was just admiring your code quality 👌