emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.63k stars 3.29k forks source link

Build error with glGetTexLevelParameteriv signature when linking wasm32 with MAXIMUM_MEMORY=4GB #19944

Closed pavshen closed 1 year ago

pavshen commented 1 year ago

At link stage (wasm32 with MAXIMUM_MEMORY=4GB) I get the following error:

error: handleI64Signatures: missing name for argument 1 in glGetTexLevelParameteriv

No error with MAXIMUM_MEMORY=2GB

I suppose it is related to #19866 fixed by https://github.com/emscripten-core/emscripten/pull/19902

Version of emscripten/emsdk:

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.44 (bec42dac7873903d09d713963e34020c22a8bd2d)
clang version 17.0.0 (https://github.com/llvm/llvm-project a8cbd27d1f238e104a5d5ca345d93bc1f4d4ab1f)
Target: wasm32-unknown-emscripten
Thread model: posix

The same error with Tag 3.1.43, no error with Tag 3.1.38.

Full link command:

emcc -v -O3 -Wl,--whole-archive EmscriptenWrapper.a -Wl,--no-whole-archive EditMode.a OverlayManager.a PhotogrammetricCalc.a SceneManager.a MapTerrain.a GeographicCalculations.a GeometricCalculations.a GridCoordinateSystems.a CommonUtils.a Codec_FreeImage.a OgreRTShaderSystem.a RenderSystem_GLES2.a OgreGLSupport.a OgreOverlay.a OgreMain.a glues.a MCgdal201.a FreeImageLib.a zziplib.a freetype.a sheenbidi.a McProj.a OsgLib.a -sEXPORT_NAME=CoreModule -sERROR_ON_UNDEFINED_SYMBOLS=0 -sWARN_ON_UNDEFINED_SYMBOLS=0 --pre-js WrapperUtils.js -lnodefs.js -lembind --preload-file FS -sMIN_WEBGL_VERSION=1  -sMAX_WEBGL_VERSION=2 -sSTACK_SIZE=5MB -o Core.js -sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=4GB

Full command output:

 "C:/Emsc/upstream/bin\clang.exe" --version
 "C:\Emsc\upstream\emscripten\tools\file_packager.bat" Core.data --from-emcc --preload FS
 "C:/Emsc/upstream/bin\wasm-ld.exe" -o Core.wasm --whole-archive EmscriptenWrapper.a --no-whole-archive EditMode.a OverlayManager.a PhotogrammetricCalc.a SceneManager.a MapTerrain.a GeographicCalculations.a GeometricCalculations.a GridCoordinateSystems.a CommonUtils.a Codec_FreeImage.a OgreRTShaderSystem.a RenderSystem_GLES2.a OgreGLSupport.a OgreOverlay.a OgreMain.a glues.a MCgdal201.a FreeImageLib.a zziplib.a freetype.a sheenbidi.a McProj.a OsgLib.a -LC:\Emsc\upstream\emscripten\cache\sysroot\lib\wasm32-emscripten --whole-archive -lembind-rtti --no-whole-archive -lGL-webgl2 -lal -lhtml5 -lstubs -lnoexit -lc -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr C:\Users\XXX\AppData\Local\Temp\tmpui9kgxjslibemscripten_js_symbols.so --import-undefined --strip-debug --export-if-defined=main --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_argc_argv --export-if-defined=stackSave --export-if-defined=stackRestore --export-if-defined=stackAlloc --export-if-defined=__errno_location --export-if-defined=__get_temp_ret --export-if-defined=__set_temp_ret --export-if-defined=malloc --export-if-defined=free --export-if-defined=__wasm_call_ctors --export-table -z stack-size=5242880 --initial-memory=16777216 --no-entry --max-memory=4294967296 --global-base=1024
 "C:/Emsc/upstream\bin\wasm-emscripten-finalize" --dyncalls-i64 --pass-arg=legalize-js-interface-exported-helpers Core.wasm -o Core.wasm --detect-features
 "C:/Emsc/node/16.20.0_64bit/bin/node.exe" C:\Emsc\upstream\emscripten\src\compiler.js C:\Users\XXX\AppData\Local\Temp\tmptr5s65i5.json
error: handleI64Signatures: missing name for argument 1 in glGetTexLevelParameteriv
Error: Aborting compilation due to previous errors
emcc: error: 'C:/Emsc/node/16.20.0_64bit/bin/node.exe C:\Emsc\upstream\emscripten\src\compiler.js C:\Users\XXX\AppData\Local\Temp\tmptr5s65i5.json' failed (returned 1)
pavshen commented 1 year ago

I merged the changes in library_glemu.js from https://github.com/emscripten-core/emscripten/commit/d482a46b335c830924e113ca3da0335c965dc6a5 into the installed Emscripten 3.1.44 and rebuilt my source. I got the same error.

sbc100 commented 1 year ago

@pavshen, because the fix in d482a46 is so obviously correct I wonder if you did something wrong when integrating the change. Can you perhaps try using ./emsdk install tot to install the latest version? I'm pretty sure the fix is good.

Failing that can you share the full error you are seeing is it identical to the one in the original report?

pavshen commented 1 year ago

@sbc100, I checked again that C:\Emsc\upstream\emscripten\src of 3.1.44 tag version contains the latest (fixed) version of library_glemu.js, cleared emscripten cache, and rebuilt again (twice). The same error:

"C:/Emsc/upstream/bin\clang.exe" --version
"C:\Emsc\upstream\emscripten\tools\file_packager.bat" Core.data --from-emcc --preload FS
"C:/Emsc/upstream/bin\wasm-ld.exe" -o Core.wasm --whole-archive EmscriptenWrapper.a --no-whole-archive EditMode.a OverlayManager.a PhotogrammetricCalc.a SceneManager.a MapTerrain.a GeographicCalculations.a GeometricCalculations.a GridCoordinateSystems.a CommonUtils.a Codec_FreeImage.a OgreRTShaderSystem.a RenderSystem_GLES2.a OgreGLSupport.a OgreOverlay.a OgreMain.a glues.a MCgdal201.a FreeImageLib.a zziplib.a freetype.a sheenbidi.a McProj.a OsgLib.a -LC:\Emsc\upstream\emscripten\cache\sysroot\lib\wasm32-emscripten --whole-archive -lembind-rtti --no-whole-archive -lGL-webgl2 -lal -lhtml5 -lstubs -lnoexit -lc -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr C:\Users\XXX\AppData\Local\Temp\tmp6bvx1lxelibemscripten_js_symbols.so --import-undefined --strip-debug --export-if-defined=main --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_argc_argv --export-if-defined=stackSave --export-if-defined=stackRestore --export-if-defined=stackAlloc --export-if-defined=__errno_location --export-if-defined=__get_temp_ret --export-if-defined=__set_temp_ret --export-if-defined=malloc --export-if-defined=free --export-if-defined=__wasm_call_ctors --export-table -z stack-size=5242880 --initial-memory=1073741824 --no-entry --max-memory=4294967296 --global-base=1024
"C:/Emsc/upstream\bin\wasm-emscripten-finalize" --dyncalls-i64 --pass-arg=legalize-js-interface-exported-helpers Core.wasm -o Core.wasm --detect-features
"C:/Emsc/node/16.20.0_64bit/bin/node.exe" C:\Emsc\upstream\emscripten\src\compiler.js C:\Users\XXX\AppData\Local\Temp\tmpqpid8w3e.json
error: handleI64Signatures: missing name for argument 1 in glGetTexLevelParameteriv
Error: Aborting compilation due to previous errors
emcc: error: 'C:/Emsc/node/16.20.0_64bit/bin/node.exe C:\Emsc\upstream\emscripten\src\compiler.js C:\Users\XXX\AppData\Local\Temp\tmpqpid8w3e.json' failed (returned 1)

When I remove glGetTexLevelParameteriv() from my code (it is not really called), there is no error.

sbc100 commented 1 year ago

I really don't understand then. Can you run grep glGetTexLevelParameteriv C:/Emsc/upstream/emscripten/src/*.js and share the output? (I guess maybe you don't have grep, but you get the idea). Do you see argument to glGetTexLevelParameteriv there like I do?

$ grep glGetTexLevelParameteriv src/*.js
src/library_glemu.js:  glGetTexLevelParameteriv: function(target, level, pname, params) { throw 'glGetTexLevelParameteriv: TODO' },
src/library_sigs.js:  glGetTexLevelParameteriv__sig: 'viiip',
pavshen commented 1 year ago

Yes, this is what I see in my C:/Emsc/upstream/emscripten/src/*.js.

sbc100 commented 1 year ago

Then I don't understand how there can be missing name for glGetTexLevelParameteriv. Very odd.

Can you try adding some debugging to figure out what is going on? Can you edit emscripten/src/jsifier.js and add error(snippet) below the existing error on line 138 (the line with the "missing name" error). Then run your link again and share the results?

pavshen commented 1 year ago

With error(snippet) added to emscripten/src/jsifier.js:

 "C:/Emsc/upstream/bin\clang.exe" --version
 "C:\Emsc\upstream\emscripten\tools\file_packager.bat" Core.data --from-emcc --preload FS
 "C:/Emsc/upstream/bin\wasm-ld.exe" -o Core.wasm --whole-archive EmscriptenWrapper.a --no-whole-archive EditMode.a OverlayManager.a PhotogrammetricCalc.a SceneManager.a MapTerrain.a GeographicCalculations.a GeometricCalculations.a GridCoordinateSystems.a CommonUtils.a Codec_FreeImage.a OgreRTShaderSystem.a RenderSystem_GLES2.a OgreGLSupport.a OgreOverlay.a OgreMain.a glues.a MCgdal201.a FreeImageLib.a zziplib.a freetype.a sheenbidi.a McProj.a OsgLib.a -LC:\Emsc\upstream\emscripten\cache\sysroot\lib\wasm32-emscripten --whole-archive -lembind-rtti --no-whole-archive -lGL-webgl2 -lal -lhtml5 -lstubs -lnoexit -lc -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr C:\Users\XXX\AppData\Local\Temp\tmpc440bbn5libemscripten_js_symbols.so --import-undefined --strip-debug --export-if-defined=main --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_argc_argv --export-if-defined=stackSave --export-if-defined=stackRestore --export-if-defined=stackAlloc --export-if-defined=__errno_location --export-if-defined=__get_temp_ret --export-if-defined=__set_temp_ret --export-if-defined=malloc --export-if-defined=free --export-if-defined=__wasm_call_ctors --export-table -z stack-size=5242880 --initial-memory=1073741824 --no-entry --max-memory=4294967296 --global-base=1024
 "C:/Emsc/upstream\bin\wasm-emscripten-finalize" --dyncalls-i64 --pass-arg=legalize-js-interface-exported-helpers Core.wasm -o Core.wasm --detect-features
 "C:/Emsc/node/16.20.0_64bit/bin/node.exe" C:\Emsc\upstream\emscripten\src\compiler.js C:\Users\XXX\AppData\Local\Temp\tmp6g2rwvcn.json
error: handleI64Signatures: missing name for argument 1 in glGetTexLevelParameteriv
error: function anonymous(
) {
err('missing function: glGetTexLevelParameteriv'); abort(-1);
}
Error: Aborting compilation due to previous errors
emcc: error: 'C:/Emsc/node/16.20.0_64bit/bin/node.exe C:\Emsc\upstream\emscripten\src\compiler.js C:\Users\XXX\AppData\Local\Temp\tmp6g2rwvcn.json' failed (returned 1)
sbc100 commented 1 year ago

Ah I see the problem. This is separate issue to the one that was fixed in d482a46. The issue is that this symbol is actually undefined and that you are linking with -sERROR_ON_UNDEFINED_SYMBOLS=0 and jsifier.js is creating a stub function, which doesn't have the correct signature. I am looking into fixing those stubs now.

BTW, do you remember why you are you linking with -sERROR_ON_UNDEFINED_SYMBOLS=0/ -sWARN_ON_UNDEFINED_SYMBOLS=0. If possible it would be good to try to remove this flags, since they can hide real issues with your application and make linker errors less useful.

pavshen commented 1 year ago

BTW, do you remember why you are you linking with -sERROR_ON_UNDEFINED_SYMBOLS=0/ -sWARN_ON_UNDEFINED_SYMBOLS=0

We have a massive multi-platform project, many modules are not compiled to wasm and not called, but we don't want to fill the code with many #ifdef's. That is why there are undefined symbols in the code that are not called in wasm.

matthewbloch commented 7 months ago

I've boiled this error down to a test case that's still occurring in 3.1.53 / releases-e5523d57a0e0dcf80f3b101bbc23613fcc3101aa-64bit:

// source ~/emsdk/emsdk_env.sh
// emsdk list
// emcc -lGL -o test test.c

#include <GL/gl.h>

int main() {
  GLint i;
  glGetIntegerv(GL_VIEWPORT, (GLint *)&i);
  //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &i);
}

It builds if I leave the call to glGetTextLevelParameterIv out, but with it I get:

wasm-ld: error: /tmp/emscripten_temp_0dx7z2vo/test_0.o: undefined symbol: glGetTexLevelParameteriv
emcc: error: '/home/mattbee/emsdk/upstream/bin/wasm-ld -o test.wasm /tmp/emscripten_temp_0dx7z2vo/test_0.o -L/home/mattbee/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten --whole-archive -lGL-getprocaddr --no-whole-archive -lal -lhtml5 -lstubs-debug -lnoexit -lc-debug -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-debug-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmp7ypezqpxlibemscripten_js_symbols.so --strip-debug --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-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 --initial-memory=16777216 --max-memory=16777216 --no-entry --stack-first --table-base=1' failed (returned 1)

I get the same error whether I've used -sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=4GB or not. I'm not using -sERROR_ON_UNDEFINED_SYMBOLS anywhere.

(later edit...) This links fine if I supply -sLEGACY_GL_EMULATION=1 but I don't yet understand why that's necessary or what the other implications might be.

sbc100 commented 7 months ago

I've boiled this error down to a test case that's still occurring in 3.1.53 / releases-e5523d57a0e0dcf80f3b101bbc23613fcc3101aa-64bit:

// source ~/emsdk/emsdk_env.sh
// emsdk list
// emcc -lGL -o test test.c

#include <GL/gl.h>

int main() {
  GLint i;
  glGetIntegerv(GL_VIEWPORT, (GLint *)&i);
  //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &i);
}

It builds if I leave the call to glGetTextLevelParameterIv out, but with it I get:

wasm-ld: error: /tmp/emscripten_temp_0dx7z2vo/test_0.o: undefined symbol: glGetTexLevelParameteriv
emcc: error: '/home/mattbee/emsdk/upstream/bin/wasm-ld -o test.wasm /tmp/emscripten_temp_0dx7z2vo/test_0.o -L/home/mattbee/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten --whole-archive -lGL-getprocaddr --no-whole-archive -lal -lhtml5 -lstubs-debug -lnoexit -lc-debug -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-debug-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmp7ypezqpxlibemscripten_js_symbols.so --strip-debug --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-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 --initial-memory=16777216 --max-memory=16777216 --no-entry --stack-first --table-base=1' failed (returned 1)

I get the same error whether I've used -sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=4GB or not. I'm not using -sERROR_ON_UNDEFINED_SYMBOLS anywhere.

(later edit...) This links fine if I supply -sLEGACY_GL_EMULATION=1 but I don't yet understand why that's necessary or what the other implications might be.

Yes glGetTextLevelParameterIv looks like a desktop GL function that we implement in library_glemu.js which only gets included at link time if you build with -sLEGACY_GL_EMULATION=1.