I have managed to successfully compile and build Ngspice for WASM with Emscripten. I have made a Docker container which encapsulates all the required components and procedures. Details can be found here:
https://github.com/danchitnis/ngspice
@h_vogt However, few problems do exist:
1. I had to remove the following section from misc_time.c due to memset
.
#ifdef HAVE_GETRUSAGE int ret; struct rusage ruse; memset(&ruse, 0, sizeof(ruse)); ret = getrusage(RUSAGE_SELF, &ruse); if(ret == -1) { perror("getrusage(): "); return 1; } return ((double)ruse.ru_utime.tv_sec + (double) ruse.ru_utime.tv_usec / 1000000.0); #else
I am not sure what this function does? It doesn't seem to have any implications when running ngspice.
2. During compilation emmake make
, there is a warning being generated that warning: unknown warning option '-Wno-unused-but-set-variable'; did you mean '-Wno-unused-const-variable'? [-Wunknown-warning-option]
. Where is the option to change the CC compiler flags in the ngspice codebase?
3. OPENMP is not supported neither in WASM nor Emscripten yet. However this might change by the introduction SIMD instructions for WASM.
4. The shared library option doesn't seem to work well with Emscripten at the moment.
It would be nice to add a WASM build to ngspice build options.
memset
is used in more than 20 places throughout the ngspice source code. So I do not understand why this one here creates problems, and the others do not.CC compiler flags are set in configure.ac (see e.g. line 238).
OpenMP may be deselected by not giving --enable-openmp during the configure step.
What does 4. mean exactly? Any error messages during compile? Any strange behavior or results?
The previous discussion in #96 said that it is not memset, but getrusage (may in combination with memset) which does not do.
So we simply have to exclude getrusage. This should be done during the configure step. In configure.ac there is a check for operating system at compile time (lines 307 ff.) Could there be an entry for Emscripten as well? We then could set a flag to exclude getrusage.
Hi Holger,
1. yes it is
getrusage
, the errors happen inmemset
, otherwisememset
is fine. We can add aenable_wasm
flag there.2. I found the CC flags, I have to test it now. These warnings happen on every file and clutter the compiler output.
3. This is fine for now.
4. I am not sure where the problem is. It seems that
emcc
is not strict enough when compiling shared libraries, and doesn't give any errors. Then, the code actually doesn't run and hardly gets past the first few lines without a fatal exit. The problem might be in the linking process. Getting the shared library working doesn't have a significant benefit over the interactive version. The reason is both run in the virtual WASM machine in a similar way.Few more step to get a clean WASM version of ngspice without any hacks!
Again looking at some blogs from internet: It is not the memset function written by ngspice people, but a _memset function that is part of the getrusage function. So getrusage seems to be basically flawed in emcc.
You may try replacing
#ifdef HAVE_GETRUSAGE
by
#if defined(HAVE_GETRUSAGE) && !defined(__EMSCRIPTEN__)
Last edit: Holger Vogt 2020-10-21
CFLAGS="$CFLAGS -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wnested-externs -Wold-style-definition -Wredundant-decls -Wconversion -Wno-unused-const-variable"
. This removed the previous unknown option warning. Can we make a separate CC flag for emscripten?getrusage
bug has disappeared! I am not sure this was due to ngspice 33 or Emscripten 2.0.7 releases. There is no need for patches or flags here.I have attached the config and make log here. Is the build process as expected? The generated wasm seems to run correctly. I will update my Docker file with these new changes.
Last edit: Danial Chitnis 2020-10-22
Yes, as soon as we know how to safely detect emscripten or emcc in configure.ac .
Last edit: Holger Vogt 2020-10-22
Please check if
-Wno-unused
is o.k. instead of
-Wno-unused-but-set-variable
-Wno-unused-const-variable
instead of
-Wno-unused-but-set-variable
works fine.
Currently, I am doing:
sed -i 's/-Wno-unused-but-set-variable/-Wno-unused-const-variable/g' ./configure.ac
I have updated the demo to show ngspice version and build timestamp
emcc seems to be not up-to-date concernig possible error message flags (compared to gcc).
In an ngspice release I will not tinker around with sed or so.
If there is a means to safely auto-detect the emscripten environment in configure.ac, I would consider adding a branch to avoid the offensive flag. Unfortunately I do not have emscripten (and I am not considering to install it locally), so I have to rely on your input here.
Last edit: Holger Vogt 2020-10-23
Hi Holger, this seems to work in
configure.ac
It has to be placed after GCC test, otherwise
$CFLAGS
will be overwritten.I am developing inside containers, so no local installation is needed. I have made a Github mirror, which eventually enables some automatic building and testing in the cloud.