Unsolved Including pybind11 causes Emscripten to fail build
-
I have a basic QML/C++ Qt app I am able to compile to WebAssembly using Emscripen.
I am trying to use pybind11 on the C++ side so I can embed Python.
It works as expected when I build and execute on my system.#if defined(_DEBUG) #undef _DEBUG #include <Python.h> #define _DEBUG #else #include <Python.h> #endif #include <pybind11/embed.h> #include <QGuiApplication> #include <QQmlApplicationEngine> #include <stdio.h> #include <iostream> using namespace std; void say_something () { printf ("Say Something nicely\n"); } static int COUNTER = 0; void set_counter (int count) { COUNTER = count; } struct MyData { float x; }; struct MyDataPython { float x; float y; MyDataPython () : x(0), y(0) {} MyDataPython (float x, float y) : x(x), y(y) {} }; PYBIND11_EMBEDDED_MODULE (embeddedmodule, module) { module.doc () = "Embedded Module"; module.def ("say_something", &say_something); module.def ("set_counter", &set_counter); pybind11::class_<MyData>(module, "MyData") .def_readwrite ("x", &MyData::x); } int main(int argc, char *argv[]) { // TESTING pybind11 stuff here ///////////////////////////////////////////////////////////////////// pybind11::scoped_interpreter guard{}; //Python executed pybind11::exec ("print('hello world')"); pybind11::exec ("from test_mod import Test"); pybind11::exec ("test = Test()"); pybind11::exec ("import embeddedmodule\nembeddedmodule.say_something()"); cout << COUNTER << '\n'; // the import from previous statement still active pybind11::exec ("embeddedmodule.set_counter(10)"); cout << COUNTER << '\n'; //////////////////////////////////////////////////////////////////// QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
When built and executed the simple app launches as expected and I see the following in Application output showing it is working:
08:34:25: Starting /home/thrive/Documents/CODE/QtFORWebAssemblyTest/build-Todo-Desktop_Qt_5_13_2_GCC_64bit-Debug/Todo ... QML debugging is enabled. Only use this in a safe environment. hello world init TEST class! Say Something nicely 0 10
But when I try to build/make this same app using Emscripten it fails:
ed@machine:~/Documents/CODE/QtFORWebAssemblyTest/Todo/build$ /home/thrive/Qt/5.13.2/wasm_32/bin/qmake .. Project MESSAGE: Setting TOTAL_MEMORY to 64MB ed@machine:~/Documents/CODE/QtFORWebAssemblyTest/Todo/build$ make em++ -c -pipe -O3 -std=gnu++11 -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_MEMORY=64MB -Wall -W -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I../../Todo -I. -I/usr/include/python3.6m -I/home/thrive/Downloads/pybind11/include -I/home/thrive/Qt/5.13.2/wasm_32/include -I/home/thrive/Qt/5.13.2/wasm_32/include/QtQuick -I/home/thrive/Qt/5.13.2/wasm_32/include/QtGui -I/home/thrive/Qt/5.13.2/wasm_32/include/QtQml -I/home/thrive/Qt/5.13.2/wasm_32/include/QtNetwork -I/home/thrive/Qt/5.13.2/wasm_32/include/QtCore -I. -I/home/thrive/.emscripten_ports/openssl/include -I/home/thrive/Qt/5.13.2/wasm_32/mkspecs/wasm-emscripten -o main.o ../main.cpp In file included from ../main.cpp:6: In file included from /usr/include/python3.6m/Python.h:8: /usr/include/python3.6m/pyconfig.h:104:3: error: unknown multiarch location for pyconfig.h # error unknown multiarch location for pyconfig.h ^ In file included from ../main.cpp:6: In file included from /usr/include/python3.6m/Python.h:53: In file included from /usr/include/python3.6m/pyport.h:4: /usr/include/python3.6m/pyconfig.h:104:3: error: unknown multiarch location for pyconfig.h # error unknown multiarch location for pyconfig.h ^ In file included from ../main.cpp:6: In file included from /usr/include/python3.6m/Python.h:53: /usr/include/python3.6m/pyport.h:686:2: error: "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)." #error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)." ^ In file included from ../main.cpp:6: In file included from /usr/include/python3.6m/Python.h:76: In file included from /usr/include/python3.6m/pymath.h:4: /usr/include/python3.6m/pyconfig.h:104:3: error: unknown multiarch location for pyconfig.h # error unknown multiarch location for pyconfig.h ^ In file included from ../main.cpp:6: In file included from /usr/include/python3.6m/Python.h:77: In file included from /usr/include/python3.6m/pytime.h:5: /usr/include/python3.6m/pyconfig.h:104:3: error: unknown multiarch location for pyconfig.h # error unknown multiarch location for pyconfig.h ^ In file included from ../main.cpp:6: In file included from /usr/include/python3.6m/Python.h:89: /usr/include/python3.6m/unicodeobject.h:68:2: error: Must define SIZEOF_WCHAR_T #error Must define SIZEOF_WCHAR_T ^ In file included from ../main.cpp:8: In file included from /home/thrive/Downloads/pybind11/include/pybind11/embed.h:12: In file included from /home/thrive/Downloads/pybind11/include/pybind11/pybind11.h:45: In file included from /home/thrive/Downloads/pybind11/include/pybind11/attr.h:13: In file included from /home/thrive/Downloads/pybind11/include/pybind11/cast.h:16: /home/thrive/Downloads/pybind11/include/pybind11/detail/internals.h:264:45: error: use of undeclared identifier 'PyGILState_Ensure' gil_scoped_acquire_local() : state (PyGILState_Ensure()) {} ^ /home/thrive/Downloads/pybind11/include/pybind11/detail/internals.h:265:39: error: use of undeclared identifier 'PyGILState_Release' ~gil_scoped_acquire_local() { PyGILState_Release(state); } ^ In file included from ../main.cpp:8: In file included from /home/thrive/Downloads/pybind11/include/pybind11/embed.h:12: /home/thrive/Downloads/pybind11/include/pybind11/pybind11.h:2182:28: warning: unused variable 'gil' [-Wunused-variable] gil_scoped_acquire gil; ^ 1 warning and 8 errors generated. shared:ERROR: compiler frontend failed to generate LLVM bitcode, halting Makefile:792: recipe for target 'main.o' failed make: *** [main.o] Error 1
When I remove these two includes from main.cpp and remove all the pybind11 code, it builds using Emscripten, so it is failing because these two includes:
#include <Python.h> #include <pybind11/embed.h>
Here is my .pro
QT += quick CONFIG += c++11 # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Refer to the documentation for the # deprecated API to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ RESOURCES += qml.qrc # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = # Additional import path used to resolve QML modules just for Qt Quick Designer QML_DESIGNER_IMPORT_PATH = # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target QMAKE_WASM_TOTAL_MEMORY=64MB LIBS += -L /usr/local/lib/python3.6m -lpython3.6m INCLUDEPATH += /usr/include/python3.6m \ /home/thrive/Downloads/pybind11/include DEPENDPATH += /usr/include/python3.6m
Anyone have any ideas on how to resolve this? Essentially the problem is including 'Python.h' and 'pybind11
-
I have never tried building python with emscripten.
You might look at this:hope this helps!