Emscripten: Error on linking after update to v2.0.7

Created on 15 Oct 2020  Â·  8Comments  Â·  Source: emscripten-core/emscripten

When updating emsdk from 2.0.6 to 2.0.7, my build chain is broken: an error is thrown on the linking step:

$ emcc --bind -s LLD_REPORT_UNDEFINED --no-entry -s ENVIRONMENT=worker -o build/browser/render.mjs build/render.o …
error: undefined symbol: __invoke_$struct_Agedge_s* (referenced by top-level compiled C/C++ code)
warning: To disable errors for undefined symbols use `-s ERROR_ON_UNDEFINED_SYMBOLS=0`
warning: ___invoke_$struct_Agedge_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_$struct_Agedge_s*_$struct_Agedge_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_$struct_Agedge_s*_$struct_Agedge_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_$struct_Agedge_s*_$struct_Agraph_s*_$struct_Agedge_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_$struct_Agedge_s*_$struct_Agraph_s*_$struct_Agedge_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_$struct_Agedge_s*_$struct_Agraph_s*_$struct_Agnode_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_$struct_Agedge_s*_$struct_Agraph_s*_$struct_Agnode_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_$struct_Agnode_s*_$struct_Agraph_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_$struct_Agnode_s*_$struct_Agraph_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_$struct_Agnode_s*_$struct_Agraph_s*_$struct_Agnode_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_$struct_Agnode_s*_$struct_Agraph_s*_$struct_Agnode_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_$struct_Agraph_s*_$struct_Agraph_s*_i8*_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_$struct_Agraph_s*_$struct_Agraph_s*_i8*_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_$struct__dt_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_$struct__dt_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_$struct__dt_s*_$struct_maze* (referenced by top-level compiled C/C++ code)
warning: ___invoke_$struct__dt_s*_$struct_maze* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_$struct_maze*_$struct_Agraph_s*_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_$struct_maze*_$struct_Agraph_s*_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_double (referenced by top-level compiled C/C++ code)
warning: ___invoke_double may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_double_$struct_Agraph_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_double_$struct_Agraph_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_$struct_Agedge_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_$struct_Agedge_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_$struct_Agnode_s*_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_$struct_Agnode_s*_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_$struct_Agraph_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_$struct_Agraph_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_$struct_Agraph_s*_$struct_Agnode_s*_i8*_$struct_stk_t* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_$struct_Agraph_s*_$struct_Agnode_s*_i8*_$struct_stk_t* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_$struct_Pedge_t*_i32_$struct_Pxy_t*_i32_$struct_Pxy_t*_$struct_Pxy_t* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_$struct_Pedge_t*_i32_$struct_Pxy_t*_i32_$struct_Pxy_t*_$struct_Pxy_t* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_$struct_Ppoly_t**_i32_$struct_polygon* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_$struct_Ppoly_t**_i32_$struct_polygon* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_$struct_Pxy_t*_$struct_Pxy_t*_$struct_Pxy_t* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_$struct_Pxy_t*_$struct_Pxy_t*_$struct_Pxy_t* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_$struct__IO_FILE*_i8*____ (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_$struct__IO_FILE*_i8*____ may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_$struct__dt_s*_i32_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_$struct__dt_s*_i32_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_$struct_pointnlink_t* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_$struct_pointnlink_t* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_$struct_sgraph*_$struct_snode*_$struct_snode* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_$struct_sgraph*_$struct_snode*_$struct_snode* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_$struct_vertex*_$struct_data* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_$struct_vertex*_$struct_data* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_i32_$struct_Pxy_t* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_i32_$struct_Pxy_t* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_i32_$struct__IO_FILE* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_i32_$struct__IO_FILE* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_i32_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_i32_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_i32_i8*____ (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_i32_i8*____ may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_i8*_$struct__IO_FILE* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_i8*_$struct__IO_FILE* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i32_i8*_i8*____ (referenced by top-level compiled C/C++ code)
warning: ___invoke_i32_i8*_i8*____ may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i8*_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_i8*_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i8*_i8*_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_i8*_i8*_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i8*_i8*_i32*_i8* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i8*_i8*_i32*_i8* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i8*_i8*_i8* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i8*_i8*_i8* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i8*_i8*_i8*_i32_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_i8*_i8*_i8*_i32_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i8_$struct_Agnode_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i8_$struct_Agnode_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i8_$struct_Agnode_s*_$struct_Agnode_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i8_$struct_Agnode_s*_$struct_Agnode_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_i8_$struct_Agraph_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_i8_$struct_Agraph_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void (referenced by top-level compiled C/C++ code)
warning: ___invoke_void may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_Agedge_s*_$struct_Agedge_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_Agedge_s*_$struct_Agedge_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_Agraph_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_Agraph_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_Agraph_s*_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_Agraph_s*_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_Agraph_s*_i32*_i32* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_Agraph_s*_i32*_i32* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_Agraph_s*_i32_i32_i32_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_Agraph_s*_i32_i32_i32_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_Pxy_t*_$struct_Pxy_t* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_Pxy_t*_$struct_Pxy_t* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct__IO_FILE*_$struct_maze*_i32_$struct_route*_$struct_epair_t* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct__IO_FILE*_$struct_maze*_i32_$struct_route*_$struct_epair_t* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct__IO_FILE*_$struct_sgraph* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct__IO_FILE*_$struct_sgraph* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct__dt_s* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct__dt_s* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct__dt_s*_i32_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct__dt_s*_i32_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_maze* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_maze* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_maze*_i32_$struct_route*_$struct_epair_t* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_maze*_i32_$struct_route*_$struct_epair_t* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_pointnlink_t**_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_pointnlink_t**_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_route*_$struct_sgraph*_$struct_snode*_$struct_snode* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_route*_$struct_sgraph*_$struct_snode*_$struct_snode* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_sgraph* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_sgraph* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_sgraph*_$struct_cell*_$struct_snode* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_sgraph*_$struct_cell*_$struct_snode* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_sgraph*_$struct_cell*_$struct_snode*_$struct_snode* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_sgraph*_$struct_cell*_$struct_snode*_$struct_snode* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_stk_t* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_stk_t* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_$struct_stk_t*_$struct_blk_t*_$struct_Agnode_s**_void($struct_Agnode_s*_i8*)*_i32($struct_Agnode_s*_i32)* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_$struct_stk_t*_$struct_blk_t*_$struct_Agnode_s**_void($struct_Agnode_s*_i8*)*_i32($struct_Agnode_s*_i32)* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_i32_$struct_pointnlink_t* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_i32_$struct_pointnlink_t* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_i32_$struct_route*_$struct_maze* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_i32_$struct_route*_$struct_maze* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_i32_i32 (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_i32_i32 may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: __invoke_void_i8*_i32_i32_i32(i8*_i8*)* (referenced by top-level compiled C/C++ code)
warning: ___invoke_void_i8*_i32_i32_i32(i8*_i8*)* may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
error: undefined symbol: emscripten_longjmp_jmpbuf (referenced by top-level compiled C/C++ code)
warning: _emscripten_longjmp_jmpbuf may need to be added to EXPORTED_FUNCTIONS if it arrives from a system library
Error: Aborting compilation due to previous errors
emcc: error: '/Users/duhamean/Documents/emsdk/node/12.9.1_64bit/bin/node /Users/duhamean/Documents/emsdk/upstream/emscripten/src/compiler.js /var/folders/8k/gj_v563n0fv6jdhqyhcrh7900000gn/T/tmpzpsynb8v.txt' failed (1)

It seems there is some breaking change in 2.0.7 which is not listed in the CHANGELOG. Note I've added -s LLD_REPORT_UNDEFINED --no-entry to print more meaningful error message, but I didn't need it with 2.0.6.

Most helpful comment

I'm actually not sure we realized when we made this change that it would be make all the existing object files invalid as inputs, but in retrospect is it quite big ABI break that we made on the LLVM side.

Going forward if we were such breaking changes again, which I imagine at some point we will, I agree it would be nice to deal with it in a better way.

The only feasible approach that I can think of would be to bake in some kind of ABI version into each object file and reject any that don't match. We may be able to do this for llvm changes.

However there are all kinds of more suble API changes that emscripten makes between releases that might not be captured by this. Perhaps we need something even more fine grained where we somehow embed the emscripten version into each object file? I don't know of any existing systems or precedent for this kind of thing or how we would implement it in the linker but I think its might be worth considering for a toolchain that changes as frequently as we do.

All 8 comments

I think this can be caused by mixing object files from an older version, that are linked with the newer emcc, as there was an ABI change regarding those invoke functions (which should not be observable).

Does a complete rebuild of all object files and libraries fix this?

I am experiencing the same issue. Complete rebuild didn't help.

I installed emscripten with brew install emscripten.
However, the problem disappeared after uninstalling emscripten with brew and re-installing it with emsdk as recommended in the documentation.

Thanks for the info @hmil

It's possible cached system libraries were the problem in that case - maybe the brew setup doesn't automatically rebuild them on each upgrade? If so, it may help others to do emcc --clear-cache in addition to rebuilding their project code.

Thank you, that fixed my problem.

Maybe it would be worth adding a note in the CHANGELOG? It's not that usual that a 0.0.x update breaks ABI backward compatibility.

Good point @aduh95 , given the reports here, this was not clear enough. I opened #12542 which will hopefully help.

I think with that, we can close this.

I ran into this error upgrading from 2.0.5 to 2.0.7. I'd read the changelog and didn't realise any of the ABI changing changes would be relevant. I use emcmake... would there be any way for it to automatically detect that it needs to recompile the object files?

I'm actually not sure we realized when we made this change that it would be make all the existing object files invalid as inputs, but in retrospect is it quite big ABI break that we made on the LLVM side.

Going forward if we were such breaking changes again, which I imagine at some point we will, I agree it would be nice to deal with it in a better way.

The only feasible approach that I can think of would be to bake in some kind of ABI version into each object file and reject any that don't match. We may be able to do this for llvm changes.

However there are all kinds of more suble API changes that emscripten makes between releases that might not be captured by this. Perhaps we need something even more fine grained where we somehow embed the emscripten version into each object file? I don't know of any existing systems or precedent for this kind of thing or how we would implement it in the linker but I think its might be worth considering for a toolchain that changes as frequently as we do.

Is the wasm features section extensible? Then we could build on that, adding an emscripten-abi-57 etc. "feature" with the ABI version. cc @tlively

Was this page helpful?
0 / 5 - 0 ratings