Используйте библиотеку ngspice в WebAssembly

Мне понадобится помощь в использовании ngspice в качестве библиотеки в проекте webassembly (wasm).

Я установил emsdk и новейшую версию emcc (1.39.20) и загрузил исходный код ngspice версии 32.

К моему величайшему удивлению, я смог скомпилировать ngspice в цель wasm, следуя этому руководству :

emconfigure  ./configure --with-ngshared --disable-debug
emmake make

(Пришлось немного подправить configure для прохождения проверок, добавив в эту строку .out.js a.out.wasm :)

# The possible output files:
ac_files="a.out a.out.js a.out.wasm conftest.exe conftest a.exe a_out.exe b.out conftest.*"

Это создало файл libngspice.so.0.0.0, на который я пытался ссылаться из кода C++. Однако это не удалось с duplicate symbol: main. Итак, казалось, что libngspice.so.0.0.0 содержит функцию main, которой не должно было быть, если я правильно понимаю назначение --with-ngshared скрипта configure.

Поэтому я вручную удалил функцию main из main.c ngspice и выполнил повторную компиляцию, используя описанный выше метод. На этот раз я смог успешно скомпилировать свой собственный проект, связав его с ngspice. Однако, когда я вызываю ngSpice_Init, я получаю следующие ошибки времени выполнения:

stderr Note: can't find init file.

exception thrown: RuntimeError: unreachable executed,@http://localhost:8001/sim.js line 1802 > WebAssembly.instantiate:wasm-function[67]:0x24e9
@http://localhost:8001/sim.js line 1802 > WebAssembly.instantiate:wasm-function[88]:0x423b
...

Минимальные воспроизводимые шаги:

  1. скомпилируйте ngspice, как указано выше
  2. скомпилируйте приведенный ниже код, используя em++ -o sim.html sim.cpp lib/libngspice.so
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "sharedspice.h"

using namespace std;


int recieve_char(char * str, int id, void* p){
    printf("recieved %s\n", str);
}

int recieve_stat(char* status, int id, void* p){
    printf("status: %s\n", status);
}

int ngexit(int status, bool unload, bool exit, int id, void* p){
    printf("exit: %d\n", status);
}

int recieve_data(vecvaluesall* data, int numstructs, int id, void* p){
    printf("data recieved: %f\n", data->vecsa[0]->creal);
}

int recieve_init_data(vecinfoall* data, int id, void* p){
    printf("init data recieved from: %d\n", id);
}

int ngrunning(bool running, int id, void* p){
    if(running){
        printf("ng is running\n");
    }else{
        printf("ng is not running\n");
    }
}


int main(){


    ngSpice_Init(&recieve_char, &recieve_stat, &ngexit,
             &recieve_data, &recieve_init_data, &ngrunning, (void*)NULL);

    char** circarray = (char**)malloc(sizeof(char*) * 7);
    circarray[0] = strdup("test array");
    circarray[1] = strdup("V1 1 0 1");
    circarray[2] = strdup("R1 1 2 1");
    circarray[3] = strdup("C1 2 0 1 ic=0");
    circarray[4] = strdup(".tran 10u 3 uic");
    circarray[5] = strdup(".end");
    circarray[6] = NULL;
    ngSpice_Circ(circarray);

    ngSpice_Command("run");


    return 0;
}

Так может ли кто-нибудь помочь мне правильно скомпилировать библиотеку ngspice для цели wasm?

(Прежде чем кто-то спросит, да, я видел этот вопрос, но это мало помогло)


person balping    schedule 22.07.2020    source источник


Ответы (1)


Я смог скомпилировать библиотеку и код моего примера после внесения нескольких изменений в исходный код ngspice. Патч и руководство по компиляции ngspice в wasm можно найти здесь .

(Проблема, приведшая к ошибке, показанной в моем вопросе, заключалась в том, что пример кода не возвращал ничего из функций, которые по сигнатуре должны возвращать int. Это не допускается в wasm.)

person balping    schedule 23.07.2020