Cross-Compilation of GNU Octave One of the complications of cross-compiling Octave to WebAssembly, which had not been encountered with the R source code, was the extensive use of Fortran common symbols blocks in the internal libraries of Octave such as odepack. C Source: liboctave/external/odepack/slsode.f C----------------------------------------------------------------------- C The following internal Common block contains C (a) variables which are local to any subroutine but whose values must C be preserved between calls to the routine ("own" variables), and C (b) variables which are communicated between subroutines. C The block SLS001 is declared in subroutines SLSODE, SINTDY, SSTODE, C SPREPJ, and SSOLSY. C Groups of variables are replaced by dummy arrays in the Common C declarations in routines where those variables are not used. C----------------------------------------------------------------------- COMMON /SLS001/ CONIT, CRATE, EL(13), ELCO(13,12), 1 HOLD, RMAX, TESCO(3,12), 1 CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, 2 INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, 3 IALTH, IPUP, LMAX, MEO, NQNYH, NSLP, 3 ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, 4 LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, 5 MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU Initially, it was not possible to cross-compile these common blocks to WebAssembly because the latest version of LLVM (v20 at the time of testing) did not support common symbol linkage. // Source: llvm/lib/MC/MCWasmStreamer.cpp void MCWasmStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size, Align ByteAlignment) { llvm_unreachable("Common symbols are not yet implemented for Wasm"); } As a temporary solution, LLVM was patched with the help of Serge Guelton to simulate common symbols as weak symbols. void MCWasmStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size, Align ByteAlignment) { - llvm_unreachable("Common symbols are not yet implemented for Wasm"); + auto *Symbol = cast(S); + getAssembler().registerSymbol(*Symbol); + Symbol->setWeak(true); + Symbol->setExternal(true); } A proper solution to enable support of common symbols is currently in progress and will likely be included in the next release of LLVM v22 (see llvm-project/pull/151478). For curious readers, the patched version of LLVM can be found here (linux only). In addition to the patches for LLVM, GNU Octave required a few minor modifications to target WebAssembly; mainly this entailed disabling the GUI functionalities and consolidating the Fortran function signatures and calling conventions. A full list of patches can be found in the recipe directory on emscripten-forge.