Open33

OMNeT++をwasmで動かす

zigenzigen

OMNeT++はQtのGUIがあるのでとりあえずQtをwasmで動かしてみる
https://doc.qt.io/qt-5/wasm.html

The known-good versions are:
Qt 5.12: 1.38.16
Qt 5.13: 1.38.27 (multithreading: 1.38.30)
Qt 5.14: 1.38.27 (multithreading: 1.38.30)
Qt 5.15: 1.39.8

とのことなのでemscripten 1.39.8とQt 5.15をdocker上で用意してみる。binaryあるらしいけど、licenseないのでとりあえずsourceからビルドしてみる。

zigenzigen

git clone git@github.com:qt/qtbase -b 5.15.2 --depth=1
docker run -it pwd:/home/qt emscripten/emsdk:1.39.8 bash
./configure -xplatform wasm-emscripten -nomake examples -prefix $PWD/qtbase
でとりあえずドキュメントに沿ってconfigureしてみる

zigenzigen

ドキュメントには make module-qtbase module-qtdeclarative [other modules] とあるけど、module-qtbaseなんてルールがないって言われる。実行する場所が間違ってんのかドキュメントが間違ってるのかわからんな。。。

とりあえずmakeしてみる

zigenzigen

どうもドキュメント通りには進まないけど、とりあえずmakeしたあと、examples/gui/rasterwindowをqmakeしてからmakeしてみたら通った。ちゃんとem++使ってるのでよさそう。

zigenzigen

host側にもどってrasterwindowのディレクトリに行ってから
docker run --rm -it -v pwd:/usr/share/nginx/html -p 8080:80 nginx
でnginx立ち上げて開いてみたら動いてた

zigenzigen

とりあえずwasmでQt動かすのはできたので、OMNeT++のQtEnvを動かしてみる。Qtのcmakeとかはqtbase/lib/cmakeとかにあるのでpath通してQtEnvまわりを書き直せば動いたりしないかなー。

OMNeT++はcmakeじゃないのでどうしようか悩ましいところだ。

zigenzigen

5.6.1にCMake仕込みながらやってみる。とりあえずomnetppのsrc/qtenvをビルドしてブラウザで画面が出るところを目標にしてみる。

最初にやらないといけないのは、commonのビルドだが、bisonでmatchexpression.tab.hを生成しないといけない。これはemcmake通してやるとダメなやつか?そもそもemcmakeってなにやってるんだ

ドキュメントは見つけられなかったけど
https://github.com/emscripten-core/emscripten/blob/main/emcmake.py をみると
いい感じに設定いじってくれるっぽい。

こんな感じで、CMakeLists.txt作って

cmake_minimum_required(VERSION 3.13)
project(omnet-wasm CXX)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(BISON REQUIRED)
find_package(FLEX REQUIRED)


bison_target(
        matchexpression
        matchexpression.y
        ${CMAKE_CURRENT_BINARY_DIR}/matchexpression.tab.cc
        COMPILE_FLAGS "--no-lines --defines --name-prefix=matchexpressionyy")


include_directories(
        ../../include
        ${CMAKE_CURRENT_BINARY_DIR}
        ${CMAKE_CURRENT_SOURCE_DIR}
)
file(GLOB SRCS ./*.cc)

add_library(common STATIC ${SRCS} ${CMAKE_CURRENT_BINARY_DIR}/matchexpression.tab.cc)

src/commonのなかで
emcmake cmake . -B build && emmake make -C build とかやったら通った。
cmakeちゃんとわかってないから、あとでドキュメント読まないと。

zigenzigen

src/qtenvのなかでqmakeしたらqtenv.priがないっていわれた。*.priファイルってなんなんだろう。

$ qmake
Cannot read /home/qt/omnetpp/src/qtenv/qtenv.pri: No such file or directory

https://wiki.qt.io/Including_.pro_Files
projectをincludeするものっぽい。とりあえず他にqtのプロジェクトなさそうだし、無視してよさそう。

生成されたMakefileを実行してみる

$ emmake make
make: ['make']
/home/qt/qtbase/bin/uic mainwindow.ui -o ui_mainwindow.h
/home/qt/qtbase/bin/uic areaselectordialog.ui -o ui_areaselectordialog.h
/home/qt/qtbase/bin/uic runselectiondialog.ui -o ui_runselectiondialog.h
/home/qt/qtbase/bin/uic stopdialog.ui -o ui_stopdialog.h
/home/qt/qtbase/bin/uic logfinddialog.ui -o ui_logfinddialog.h
/home/qt/qtbase/bin/uic logfilterdialog.ui -o ui_logfilterdialog.h
/home/qt/qtbase/bin/uic preferencesdialog.ui -o ui_preferencesdialog.h
/home/qt/qtbase/bin/uic rununtildialog.ui -o ui_rununtildialog.h
/home/qt/qtbase/bin/uic comboselectiondialog.ui -o ui_comboselectiondialog.h
/home/qt/qtbase/bin/uic layersdialog.ui -o ui_layersdialog.h
/home/qt/qtbase/bin/uic fileeditor.ui -o ui_fileeditor.h
/home/qt/qtbase/bin/uic animationcontrollerdialog.ui -o ui_animationcontrollerdialog.h
/home/qt/qtbase/bin/uic findobjectsdialog.ui -o ui_findobjectsdialog.h
/home/qt/qtbase/bin/uic outputvectorinspectorconfigdialog.ui -o ui_outputvectorinspectorconfigdialog.h
/home/qt/qtbase/bin/uic histograminspectorconfigdialog.ui -o ui_histograminspectorconfigdialog.h
/home/qt/qtbase/bin/uic messageprintertagsdialog.ui -o ui_messageprintertagsdialog.h
/home/qt/qtbase/bin/uic videorecordingdialog.ui -o ui_videorecordingdialog.h
em++ -c -pipe -Wall -Wextra -Wno-unused-parameter -Wno-microsoft-enum-value -O2 -std=gnu++1y -s ALLOW_MEMORY_GROWTH=1 -DQT_NO_EMIT -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_PRINTSUPPORT_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -I. -I../../../../src -I../../../../include -I.. -I../../include -I../../../qtbase/include -I../../../qtbase/include/QtOpenGL -I../../../qtbase/include/QtPrintSupport -I../../../qtbase/include/QtWidgets -I../../../qtbase/include/QtGui -I../../../qtbase/include/QtCore -I. -I../../../qtbase/mkspecs/wasm-emscripten -o mainwindow.o mainwindow.cc
mainwindow.cc:36:10: fatal error: 'common/ver.h' file not found
#include "common/ver.h"
         ^~~~~~~~~~~~~~
1 error generated.
shared:ERROR: '/emsdk/upstream/bin/clang++ -target wasm32-unknown-emscripten -D__EMSCRIPTEN_major__=1 -D__EMSCRIPTEN_minor__=39 -D__EMSCRIPTEN_tiny__=8 -D_LIBCPP_ABI_VERSION=2 -Dunix -D__unix -D__unix__ -Werror=implicit-function-declaration -Xclang -nostdsysteminc -Xclang -isystem/emsdk/upstream/emscripten/system/include/libcxx -Xclang -isystem/emsdk/upstream/emscripten/system/lib/libcxxabi/include -Xclang -isystem/emsdk/upstream/emscripten/system/include/compat -Xclang -isystem/emsdk/upstream/emscripten/system/include -Xclang -isystem/emsdk/upstream/emscripten/system/include/libc -Xclang -isystem/emsdk/upstream/emscripten/system/lib/libc/musl/arch/emscripten -Xclang -isystem/emsdk/upstream/emscripten/system/local/include -Xclang -isystem/emsdk/.data/cache/wasm-obj/include -c -pipe -Wall -Wextra -Wno-unused-parameter -Wno-microsoft-enum-value -O2 -std=gnu++1y -DQT_NO_EMIT -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_PRINTSUPPORT_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -I. -I../../../../src -I../../../../include -I.. -I../../include -I../../../qtbase/include -I../../../qtbase/include/QtOpenGL -I../../../qtbase/include/QtPrintSupport -I../../../qtbase/include/QtWidgets -I../../../qtbase/include/QtGui -I../../../qtbase/include/QtCore -I. -I../../../qtbase/mkspecs/wasm-emscripten -DEMSCRIPTEN mainwindow.cc -Xclang -isystem/emsdk/upstream/emscripten/system/include/SDL -c -o mainwindow.o -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr' failed (1)
make: *** [Makefile:15840: mainwindow.o] Error 1

src/common/ver.hは普通にビルドした時に生成されるversionを記したファイルだけど、cmakeで置き換えようとしてるので生成し忘れたやつだな。適当に既存のやつをパクって置いておこう。

もしかして別にcmake使わなくても普通にmakeで押し通してどうにかなるかもしれないなー。
emconfigureがあるなら、それで動くのかもしれない。

zigenzigen

buildしてみた後に気づいたけど、qtenv.proに

# THIS FILE IS NO LONGER USED FOR BUILDING QTENV.

って書いてあったわ。。。とりあえずlibqtenv.aを手に入れた

zigenzigen

eventlogwriterとかはファイルがないって怒られるので同名のplファイルをperlに食わせるとファイルが生成される。この辺、cmakeでうまくやるにはどうしたらいいんだろう。。。
とりあえずいい感じにコンパイルまではできたけどリンクがこける。
sqlite3まわりの関数はcommonの中にあってlibcommon.aの中にシンボルはある。適切にライブラリが指定できてない?

[ 74%] Linking CXX executable simulator.js
Reaping winning child 0x5564566923a0 PID 2364
/usr/bin/cmake -E cmake_link_script CMakeFiles/simulator.dir/link.txt --verbose=1
Live child 0x5564566923a0 (simulator.js) PID 2366
/emsdk/upstream/emscripten/em++     @CMakeFiles/simulator.dir/objects1.rsp  -o simulator.js @CMakeFiles/simulator.dir/linklibs.rsp
error: undefined symbol: _Z17doParseExpressionPKcPN7omnetpp6common10Expression8ResolverERPNS3_4ElemERi
warning: Link with `-s LLD_REPORT_UNDEFINED` to get more information on undefined symbols
warning: To disable errors for undefined symbols use `-s ERROR_ON_UNDEFINED_SYMBOLS=0`
error: undefined symbol: sqlite3_bind_double
error: undefined symbol: sqlite3_bind_int
error: undefined symbol: sqlite3_bind_int64
error: undefined symbol: sqlite3_bind_text
error: undefined symbol: sqlite3_busy_timeout
error: undefined symbol: sqlite3_clear_bindings
error: undefined symbol: sqlite3_close
error: undefined symbol: sqlite3_errmsg
error: undefined symbol: sqlite3_exec
error: undefined symbol: sqlite3_finalize
error: undefined symbol: sqlite3_last_insert_rowid
error: undefined symbol: sqlite3_open
error: undefined symbol: sqlite3_prepare_v2
error: undefined symbol: sqlite3_reset
error: undefined symbol: sqlite3_step
Error: Aborting compilation due to previous errors
shared:ERROR: '/emsdk/node/12.9.1_64bit/bin/node /emsdk/upstream/emscripten/src/compiler.js /tmp/tmplgvYke.txt' failed (1)
Reaping losing child 0x5564566923a0 PID 2366
make[2]: *** [CMakeFiles/simulator.dir/build.make:94: simulator.js] Error 1
Removing child 0x5564566923a0 PID 2366 from chain.
make[2]: Leaving directory '/home/qt/omnetpp/src/build'
Reaping losing child 0x55eda752ad20 PID 2363
make[1]: *** [CMakeFiles/Makefile2:79: CMakeFiles/simulator.dir/all] Error 2
Removing child 0x55eda752ad20 PID 2363 from chain.
zigenzigen

雑にglobで.ccでソースコード集めてたのでcommonのsqlite3.cに気づかなかった。projectの言語設定をC CXX に設定したらsqlite3のsymbolがないってエラーは消えた。
で、次のエラーはこれ

[ 74%] Linking CXX executable simulator.js
/usr/bin/cmake -E cmake_link_script CMakeFiles/simulator.dir/link.txt --verbose=1
/emsdk/upstream/emscripten/em++     @CMakeFiles/simulator.dir/objects1.rsp  -o simulator.js @CMakeFiles/simulator.dir/linklibs.rsp
error: undefined symbol: _Z17doParseExpressionPKcPN7omnetpp6common10Expression8ResolverERPNS3_4ElemERi
warning: Link with `-s LLD_REPORT_UNDEFINED` to get more information on undefined symbols
warning: To disable errors for undefined symbols use `-s ERROR_ON_UNDEFINED_SYMBOLS=0`
Error: Aborting compilation due to previous errors
shared:ERROR: '/emsdk/node/12.9.1_64bit/bin/node /emsdk/upstream/emscripten/src/compiler.js /tmp/tmpLfNqdQ.txt' failed (1)
make[2]: *** [CMakeFiles/simulator.dir/build.make:94: simulator.js] Error 1
make[2]: Leaving directory '/home/qt/omnetpp/src/build'
make[1]: *** [CMakeFiles/Makefile2:79: CMakeFiles/simulator.dir/all] Error 2
make[1]: Leaving directory '/home/qt/omnetpp/src/build'
make: *** [Makefile:87: all] Error 2
make: Leaving directory '/home/qt/omnetpp/src/build'
zigenzigen

commonの中でbisonとflexまわすの忘れてたので追記して解決

bison_target(
        matchexpression 
        matchexpression.y 
        ${CMAKE_CURRENT_BINARY_DIR}/matchexpression.tab.cc 
        COMPILE_FLAGS "--no-lines --defines --name-prefix=matchexpressionyy")
bison_target(
        expression 
        expression.y 
        ${CMAKE_CURRENT_BINARY_DIR}/expression.tab.cc 
        COMPILE_FLAGS "--defines --name-prefix=expressionyy")
flex_target(
        expression
        expression.lex
        ${CMAKE_CURRENT_BINARY_DIR}/lex.expressionyy.cc
        COMPILE_FLAGS "--prefix=expressionyy"
)
zigenzigen

qtenvはqmakeでビルドできたけど、これをcmakeからいい感じに呼ぶの、どうやったらいいんだろう。
まぁとりあえずcmakeでいけそうだからcmakeで書き直してみよう。.proファイルはもう使われてないっていうのもあるし。

https://doc.qt.io/qt-5/cmake-get-started.html

zigenzigen

cmake設定してみたけど、Qt5Config.cmakeとかがないって怒られる。emcmake cmakeで見に行くのは、/emsdk/upstream/emscripten/system とかの中なので、ここにちゃんとインストールしないといけない。make installの使い方がいまいちわからなかったので、最初にビルドしたqtをemscriptenの中に突っ込んで調整したらcmakeは通った。

というわけでmakeしてみたら次のエラーが出た。

[  1%] Automatic MOC and UIC for target qtenv
make[2]: Leaving directory '/home/qt/omnetpp/src/qtenv/build'
[  1%] Built target qtenv_autogen
make[2]: Entering directory '/home/qt/omnetpp/src/qtenv/build'
[  2%] Automatic RCC for icons.qrc
Scanning dependencies of target qtenv
make[2]: Leaving directory '/home/qt/omnetpp/src/qtenv/build'
make[2]: Entering directory '/home/qt/omnetpp/src/qtenv/build'
[  3%] Building CXX object CMakeFiles/qtenv.dir/animationcontrollerdialog.cc.o
In file included from /home/qt/omnetpp/src/qtenv/animationcontrollerdialog.cc:17:
In file included from /home/qt/omnetpp/src/qtenv/animationcontrollerdialog.h:21:
In file included from /home/qt/omnetpp/src/qtenv/qtenvdefs.h:26:
In file included from /home/qt/omnetpp/src/qtenv/../../include/omnetpp/cmessage.h:23:
In file included from /home/qt/omnetpp/src/qtenv/../../include/omnetpp/csimulation.h:21:
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:855:35: error: expected ')'
    virtual void emit(simsignal_t signalID, bool b, cObject *details = nullptr);
                                  ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:855:22: note: to match this '('
    virtual void emit(simsignal_t signalID, bool b, cObject *details = nullptr);
                     ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:855:5: error: 'virtual' can only appear on non-static member functions
    virtual void emit(simsignal_t signalID, bool b, cObject *details = nullptr);
    ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:855:23: error: field has incomplete type 'void'
    virtual void emit(simsignal_t signalID, bool b, cObject *details = nullptr);
                      ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:862:35: error: expected ')'
    virtual void emit(simsignal_t signalID, long l, cObject *details = nullptr);
                                  ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:862:22: note: to match this '('
    virtual void emit(simsignal_t signalID, long l, cObject *details = nullptr);
                     ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:862:5: error: 'virtual' can only appear on non-static member functions
    virtual void emit(simsignal_t signalID, long l, cObject *details = nullptr);
    ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:862:23: error: field has incomplete type 'void'
    virtual void emit(simsignal_t signalID, long l, cObject *details = nullptr);
                      ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:862:23: error: duplicate member 'simsignal_t'
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:855:23: note: previous declaration is here
    virtual void emit(simsignal_t signalID, bool b, cObject *details = nullptr);
                      ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:869:35: error: expected ')'
    virtual void emit(simsignal_t signalID, unsigned long l, cObject *details = nullptr);
                                  ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:869:22: note: to match this '('
    virtual void emit(simsignal_t signalID, unsigned long l, cObject *details = nullptr);
                     ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:869:5: error: 'virtual' can only appear on non-static member functions
    virtual void emit(simsignal_t signalID, unsigned long l, cObject *details = nullptr);
    ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:869:23: error: field has incomplete type 'void'
    virtual void emit(simsignal_t signalID, unsigned long l, cObject *details = nullptr);
                      ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:869:23: error: duplicate member 'simsignal_t'
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:855:23: note: previous declaration is here
    virtual void emit(simsignal_t signalID, bool b, cObject *details = nullptr);
                      ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:876:35: error: expected ')'
    virtual void emit(simsignal_t signalID, double d, cObject *details = nullptr);
                                  ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:876:22: note: to match this '('
    virtual void emit(simsignal_t signalID, double d, cObject *details = nullptr);
                     ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:876:5: error: 'virtual' can only appear on non-static member functions
    virtual void emit(simsignal_t signalID, double d, cObject *details = nullptr);
    ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:876:23: error: field has incomplete type 'void'
    virtual void emit(simsignal_t signalID, double d, cObject *details = nullptr);
                      ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:876:23: error: duplicate member 'simsignal_t'
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:855:23: note: previous declaration is here
    virtual void emit(simsignal_t signalID, bool b, cObject *details = nullptr);
                      ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:883:35: error: expected ')'
    virtual void emit(simsignal_t signalID, const SimTime& t, cObject *details = nullptr);
                                  ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:883:22: note: to match this '('
    virtual void emit(simsignal_t signalID, const SimTime& t, cObject *details = nullptr);
                     ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:883:5: error: 'virtual' can only appear on non-static member functions
    virtual void emit(simsignal_t signalID, const SimTime& t, cObject *details = nullptr);
    ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:883:23: error: field has incomplete type 'void'
    virtual void emit(simsignal_t signalID, const SimTime& t, cObject *details = nullptr);
                      ^
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:883:23: error: duplicate member 'simsignal_t'
/home/qt/omnetpp/src/qtenv/../../include/omnetpp/ccomponent.h:855:23: note: previous declaration is here
    virtual void emit(simsignal_t signalID, bool b, cObject *details = nullptr);
                      ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
shared:ERROR: '/emsdk/upstream/bin/clang++ -target wasm32-unknown-emscripten -D__EMSCRIPTEN_major__=1 -D__EMSCRIPTEN_minor__=39 -D__EMSCRIPTEN_tiny__=8 -D_LIBCPP_ABI_VERSION=2 -Dunix -D__unix -D__unix__ -Werror=implicit-function-declaration -Xclang -nostdsysteminc -Xclang -isystem/emsdk/upstream/emscripten/system/include/libcxx -Xclang -isystem/emsdk/upstream/emscripten/system/lib/libcxxabi/include -Xclang -isystem/emsdk/upstream/emscripten/system/include/compat -Xclang -isystem/emsdk/upstream/emscripten/system/include -Xclang -isystem/emsdk/upstream/emscripten/system/include/libc -Xclang -isystem/emsdk/upstream/emscripten/system/lib/libc/musl/arch/emscripten -Xclang -isystem/emsdk/upstream/emscripten/system/local/include -Xclang -isystem/emsdk/.data/cache/wasm-obj/include -DQT_CORE_LIB -DQT_EGL_SUPPORT_LIB -DQT_EVENTDISPATCHER_SUPPORT_LIB -DQT_FONTDATABASE_SUPPORT_LIB -DQT_GUI_LIB -DQT_NO_DEBUG -DQT_WIDGETS_LIB -I/home/qt/omnetpp/src/qtenv/build/qtenv_autogen/include -I/home/qt/omnetpp/src/qtenv/../../include -I/home/qt/qtbase/include/QtWidgets -I/home/qt/qtbase/include -I/home/qt/omnetpp/src/qtenv -isystem /emsdk/upstream/emscripten/system/include -isystem /emsdk/upstream/emscripten/system/include/QtWidgets -isystem /emsdk/upstream/emscripten/system/include/QtGui -isystem /emsdk/upstream/emscripten/system/include/QtCore -isystem /emsdk/upstream/emscripten/system/../mkspecs/wasm-emscripten -isystem /emsdk/upstream/emscripten/system/include/QtEventDispatcherSupport -isystem /emsdk/upstream/emscripten/system/include/QtFontDatabaseSupport -isystem /emsdk/upstream/emscripten/system/include/QtEglSupport -std=c++14 -c -DEMSCRIPTEN /home/qt/omnetpp/src/qtenv/animationcontrollerdialog.cc -Xclang -isystem/emsdk/upstream/emscripten/system/include/SDL -c -o CMakeFiles/qtenv.dir/animationcontrollerdialog.cc.o -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr' failed (1)
make[2]: *** [CMakeFiles/qtenv.dir/build.make:157: CMakeFiles/qtenv.dir/animationcontrollerdialog.cc.o] Error 1
make[2]: Leaving directory '/home/qt/omnetpp/src/qtenv/build'
make[1]: *** [CMakeFiles/Makefile2:73: CMakeFiles/qtenv.dir/all] Error 2
make[1]: Leaving directory '/home/qt/omnetpp/src/qtenv/build'
make: *** [Makefile:84: all] Error 2
make: Leaving directory '/home/qt/omnetpp/src/qtenv/build'
zigenzigen

とりあえずこのエラーはおいといて、他のdependenciesをビルドしていく。

とりあえずlibxml2から。autogen.shを動かしてもうまくいかないし、emconfigureを仕込んでくれないので、
$ autoreconf -if -Wall で環境作って emmake make した。正直、この辺のツールいまいちわからんのよなー

Making all in .
make[4]: Entering directory '/root/libxml2/python'
  CC       libxml.lo
libxml.c:15:10: fatal error: 'Python.h' file not found
#include <Python.h>
         ^~~~~~~~~~
1 error generated.
shared:ERROR: '/emsdk/upstream/bin/clang -target wasm32-unknown-emscripten -D__EMSCRIPTEN_major__=1 -D__EMSCRIPTEN_minor__=39 -D__EMSCRIPTEN_tiny__=8 -D_LIBCPP_ABI_VERSION=2 -Dunix -D__unix -D__unix__ -Werror=implicit-function-declaration -Xclang -nostdsysteminc -Xclang -isystem/emsdk/upstream/emscripten/system/include/libcxx -Xclang -isystem/emsdk/upstream/emscripten/system/lib/libcxxabi/include -Xclang -isystem/emsdk/upstream/emscripten/system/include/compat -Xclang -isystem/emsdk/upstream/emscripten/system/include -Xclang -isystem/emsdk/upstream/emscripten/system/include/libc -Xclang -isystem/emsdk/upstream/emscripten/system/lib/libc/musl/arch/emscripten -Xclang -isystem/emsdk/upstream/emscripten/system/local/include -Xclang -isystem/emsdk/upstream/emscripten/cache/wasm-obj/include -DHAVE_CONFIG_H -I. -I.. -I../include -I../include -I/usr/include/python2.7 -gline-tables-only -O2 -MT libxml.lo -MD -MP -MF .deps/libxml.Tpo -c -fPIC -DPIC -DEMSCRIPTEN libxml.c -Xclang -isystem/emsdk/upstream/emscripten/system/include/SDL -c -o .libs/libxml.o -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr' failed (1)
make[4]: *** [Makefile:634: libxml.lo] Error 1
make[4]: Leaving directory '/root/libxml2/python'
make[3]: *** [Makefile:695: all-recursive] Error 1
make[3]: Leaving directory '/root/libxml2/python'
make[2]: *** [Makefile:529: all] Error 2
make[2]: Leaving directory '/root/libxml2/python'
make[1]: *** [Makefile:1481: all-recursive] Error 1
make[1]: Leaving directory '/root/libxml2'
make: *** [Makefile:895: all] Error 2
[root@86f339cd0971 libxml2]#

Python.h何に使うんだ。。。オプション吟味してこよう。

zigenzigen

さっきのエラーは--without-pythonしたらいけた。configure.acとか見ながらoption決める。
とりあえずこんな感じでconfigureしてからmake
$ emconfigure ./configure --without-python --without-ftp --without-threads --without-html --without-zlib --without-lzma
$ emmake make

参考
https://github.com/matiasinsaurralde/wasm-libxml2

zigenzigen

なんとなくcmakeでomnetppのビルドをやるのに限界を感じてきたので、とりあえず素直に
configure.userをいじってQTENVだけを使ってstatic buildに設定してから
$ emconfigure configure
して
$ MODE=debug emmake make
したら、ビルド通った。
.msg ファイルに関しては事前にホスト側でCのファイルに変換しておく必要がある。

zigenzigen

omnetppのMakefile.incでARFLAG_OUTにrcs を指定しておく必要がある。最後のスペースが大事。
最後にリンクするときはどうにか em++に -Wl,--whole-archive を渡しておかないと、Qtenvのシンボルがバイナリに含まれないので死ぬ。
Qtが内部でlibpng使ってるので、これはem++に -s USE_LIBPNG=を渡して、portingされたlibpngを使うようにする

zigenzigen

samples/tictocの中でobject作ったあとにこれでリンクしたらとりあえずいけた。--bindいれたらなんか挙動かわって動かねえ。。。とりあえずQt系は一通りリンクできたっぽい

[root@e389ee936b0b tictoc]$ /emsdk/upstream/emscripten/em++ -L/home/qt/omnetpp/lib -s EXCEPTION_DEBUG=1 -s DISABLE_EXCEPTION_CATCHING=0 --post-js pre.js --js-opts 0 -g4 -O0 --source-map-base http://localhost:8080/samples/tictoc/out/emcc-debug/ --preload-file ./omnetpp.ini --preload-file ./tictoc1.ned --preload-file ./package.ned -o out/emcc-debug//tictoc_dbg.html out/emcc-debug//txc1.o out/emcc-debug//txc10.o out/emcc-debug//txc11.o out/emcc-debug//txc12.o out/emcc-debug//txc13.o out/emcc-debug//txc14.o out/emcc-debug//txc15.o out/emcc-debug//txc16.o out/emcc-debug//txc17.o out/emcc-debug//txc18.o out/emcc-debug//txc2.o out/emcc-debug//txc3.o out/emcc-debug//txc4.o out/emcc-debug//txc5.o out/emcc-debug//txc6.o out/emcc-debug//txc7.o out/emcc-debug//txc8.o out/emcc-debug//txc9.o out/emcc-debug//tictoc13_m.o out/emcc-debug//tictoc14_m.o out/emcc-debug//tictoc15_m.o out/emcc-debug//tictoc16_m.o out/emcc-debug//tictoc17_m.o out/emcc-debug//tictoc18_m.o -Wl,--whole-archive -loppqtenv_dbg -loppcommon_dbg -loppsim_dbg -L/home/qt/qtbase/lib -lQt5Core -lQt5GUI -lQt5Widgets -lQt5PrintSupport -lQt5OpenGL -loppenvir_dbg -lopplayout_dbg  -loppnedxml_dbg -lqtpcre2 -lqtlibpng -lqtharfbuzz --bind
zigenzigen

あれこれ追加してこう

/emsdk/upstream/emscripten/em++ -L/home/qt/omnetpp/lib -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -s EXCEPTION_DEBUG=1 -s DISABLE_EXCEPTION_CATCHING=0 --post-js pre.js --js-opts 0 -g4 -O0 --source-map-base http://localhost:8080/samples/tictoc/out/emcc-debug/ --preload-file ./omnetpp.ini --preload-file ./tictoc1.ned --preload-file ./package.ned -o out/emcc-debug//tictoc_dbg.html out/emcc-debug//txc1.o out/emcc-debug//txc10.o out/emcc-debug//txc11.o out/emcc-debug//txc12.o out/emcc-debug//txc13.o out/emcc-debug//txc14.o out/emcc-debug//txc15.o out/emcc-debug//txc16.o out/emcc-debug//txc17.o out/emcc-debug//txc18.o out/emcc-debug//txc2.o out/emcc-debug//txc3.o out/emcc-debug//txc4.o out/emcc-debug//txc5.o out/emcc-debug//txc6.o out/emcc-debug//txc7.o out/emcc-debug//txc8.o out/emcc-debug//txc9.o out/emcc-debug//tictoc13_m.o out/emcc-debug//tictoc14_m.o out/emcc-debug//tictoc15_m.o out/emcc-debug//tictoc16_m.o out/emcc-debug//tictoc17_m.o out/emcc-debug//tictoc18_m.o -Wl,--whole-archive -loppqtenv_dbg -loppcommon_dbg -loppsim_dbg -L/home/qt/qtbase/lib -lQt5Core -lQt5GUI -lQt5Widgets -lQt5PrintSupport -lQt5OpenGL -loppenvir_dbg -lopplayout_dbg  -loppnedxml_dbg -lqtpcre2 -lqtlibpng -lqtharfbuzz -loppmain_dbg --bind --preload-file images -s ALLOW_MEMORY_GROWTH=1 -L/home/qt/qtbase/plugins/platforms/ -lqwasm -lQt5EventDispatcherSupport -lQt5FontDatabaseSupport -lqtfreetype -lQt5EglSupport -L/home/qt/qtbase/plugins/imageformats/ -lqgif -lqico  -s FULL_ES2=1 -s FULL_ES3=1 -s USE_WEBGL2=1 -s EXIT_RUNTIME=1 -s ERROR_ON_UNDEFINED_SYMBOLS=1 -s EXTRA_EXPORTED_RUNTIME_METHODS=["UTF16ToString","stringToUTF16"]

NEDファイルの読み込みまではきた

qtのpluginの初期化まわりでこけてる。

zigenzigen

ログ出すのにQ=とか渡してたけど、よくよくMakefile.inc読んでたら、V=1 emmake make でちゃんとコマンド表示されるわ

zigenzigen

ようやくsampleのtictocが動いた。step実行はできるけど、runすると固まる。ひたすらイベントループが延々まわってるだけらしい。

zigenzigen

configを変えようとしてダイアログを出すと、asyncサポートがないって怒られた

zigenzigen

thread周りを直してちゃんと動くようにしようと思ったんだけど、よくよくみてるといまのqt5.15, emscripten 1.39.8だと動かない可能性が高い。fastcompがサポートされなくなったかららしい。
https://wiki.qt.io/Qt_for_WebAssembly

zigenzigen

https://v8.dev/blog/emscripten-llvm-wasm
うーん、EmterpreterとAsyncifyとThreadまわりのドキュメントをよく読んでみるか。新しいバックエンドでうまくビルドできれば、バージョン変えなくていいので楽なんだよなー。

zigenzigen

export指定してた気がするんだけどな

print err:  exception thrown: abort('stringToUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)) at Error
    at jsStackTrace (eval at completeLoadEmscriptenModule (http://localhost:8000/samples/tictoc/out/emcc-debug/qtloader.js:443:14), <anonymous>:2017:17)
    at stackTrace (eval at completeLoadEmscriptenModule (http://localhost:8000/samples/tictoc/out/emcc-debug/qtloader.js:443:14), <anonymous>:2034:16)
    at abort (eval at completeLoadEmscriptenModule (http://localhost:8000/samples/tictoc/out/emcc-debug/qtloader.js:443:14), <anonymous>:1773:44)
    at Module.stringToUTF16 (eval at completeLoadEmscriptenModule (http://localhost:8000/samples/tictoc/out/emcc-debug/qtloader.js:443:14), <anonymous>:17219:103)
    at __emval_call (eval at completeLoadEmscriptenModule (http://localhost:8000/samples/tictoc/out/emcc-debug/qtloader.js:443:14), <anonymous>:7472:23)
    at __ZN11QWasmString9toQStringERKN10emscripten3valE (http://localhost:8000/samples/tictoc/out/emcc-debug/tictoc_dbg.wasm:wasm-function[8070]:0x11193f5)
    at __ZN16QWasmIntegrationC2Ev (http://localhost:8000/samples/tictoc/out/emcc-debug/tictoc_dbg.wasm:wasm-function[7821]:0x11027df)
    at __ZN22QWasmIntegrationPlugin6createERK7QStringRK11QStringList (http://localhost:8000/samples/tictoc/out/emcc-debug/tictoc_dbg.wasm:wasm-function[7803]:0x11010f3)
    at __ZN26QPlatformIntegrationPlugin6createERK7QStringRK11QStringListRiPPc (http://localhost:8000/samples/tictoc/out/emcc-debug/tictoc_dbg.wasm:wasm-function[9047]:0x112b3ed)
    at __Z11qLoadPluginI20QPlatformIntegration26QPlatformIntegrationPluginJRK11QStringListRiRPPcEEPT_PK14QFactoryLoaderRK7QStringDpOT1_ (http://localhost:8000/samples/tictoc/out/emcc-debug/tictoc_dbg.wasm:wasm-function[9011]:0x112ab89)
Module.printErr @ qtloader.js:382
callMain @ VM9:17393
doRun @ VM9:17433
eval @ VM9:17444
setTimeout (async)
run @ VM9:17440
runCaller @ VM9:17350
removeRunDependency @ VM9:1750
eval @ VM9:1783
worker.onmessage @ VM9:2348

zigenzigen

https://stackoverflow.com/questions/59765945/wasm-link-error-function-signature-mismatch
ここで言われてるように RuntimeError: function signature mismatch というエラーに大した意味はなくて、
-s ASSERTIONS=2 -s SAFE_HEAP=1 -s STACK_OVERFLOW_CHECK=1 をつけて正しいエラーを確認しないといけない。

試したらいい感じにセグフォしてるっぽい

VM42:6911 Uncaught RuntimeError: abort(segmentation fault) at Error
    at jsStackTrace (eval at completeLoadEmscriptenModule (qtloader.js:443), <anonymous>:7539:14)
    at stackTrace (eval at completeLoadEmscriptenModule (qtloader.js:443), <anonymous>:7554:11)
    at abort (eval at completeLoadEmscriptenModule (qtloader.js:443), <anonymous>:6909:43)
    at segfault (eval at completeLoadEmscriptenModule (qtloader.js:443), <anonymous>:6271:2)
    at SAFE_HEAP_LOAD_i32_4_4 (main.cc:31)
    at QGraphicsItem::isVisible() const (fpathconf.c:34)
    at omnetpp::qtenv::MessageItem::boundingRect() const (messageitem.cc:245)
    at non-virtual thunk to omnetpp::qtenv::MessageItem::boundingRect() const (messageitem.cc:245)
    at QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem*, bool, double) (new.cpp:116)
    at QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem*, bool, double) (new.cpp:116)
    at abort (eval at completeLoadEmscriptenModule (qtloader.js:443), <anonymous>:6911:10)
    at segfault (eval at completeLoadEmscriptenModule (qtloader.js:443), <anonymous>:6271:2)
    at SAFE_HEAP_LOAD_i32_4_4 (main.cc:31)
    at QGraphicsItem::isVisible() const (fpathconf.c:34)
    at omnetpp::qtenv::MessageItem::boundingRect() const (messageitem.cc:245)
    at non-virtual thunk to omnetpp::qtenv::MessageItem::boundingRect() const (messageitem.cc:245)
    at QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem*, bool, double) (new.cpp:116)
    at QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem*, bool, double) (new.cpp:116)
    at QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem*, bool, double) (new.cpp:116)
    at QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem*, bool, double) (new.cpp:116)
abort	@	VM42:6911
segfault	@	VM42:6271
$SAFE_HEAP_LOAD_i32_4_4	@	main.cc:31
$QGraphicsItem::isVisible() const	@	fpathconf.c:34
$omnetpp::qtenv::MessageItem::boundingRect() const	@	messageitem.cc:245
$non-virtual thunk to omnetpp::qtenv::MessageItem::boundingRect() const	@	messageitem.cc:245
$QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem*, bool, double)	@	new.cpp:116
$QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem*, bool, double)	@	new.cpp:116
$QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem*, bool, double)	@	new.cpp:116
$QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem*, bool, double)	@	new.cpp:116
$QGraphicsScene::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)	@	new.cpp:116
$QMetaCallEvent::placeMetaCall(QObject*)	@	pthread_self.c:7
$QObject::event(QEvent*)	@	pthread_self.c:7
$QGraphicsScene::event(QEvent*)	@	new.cpp:116
$QApplicationPrivate::notify_helper(QObject*, QEvent*)	@	getuid.c:6
$QApplication::notify(QObject*, QEvent*)	@	getuid.c:6
$QCoreApplication::notifyInternal2(QObject*, QEvent*)	@	new.cpp:116
$QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*)	@	new.cpp:116
$QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)	@	__errno_location.c:8
$QUnixEventDispatcherQPA::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)	@	new.cpp:116
$QWasmEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)	@	qrc_icons.cpp:3856
$QWasmEventDispatcher::mainThreadWakeUp(void*)	@	library_pthread.c:816
$_do_call	@	library_pthread.c:245
$emscripten_current_thread_process_queued_calls	@	library_pthread.c:690
$emscripten_main_thread_process_queued_calls	@	library_pthread.c:714
eval	@	VM42:6937
worker.onmessage	@	VM42:7436