Problems with Open-Source Downloads read https://www.qt.io/blog/problem-with-open-source-downloads and https://forum.qt.io/post/638946

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


Log in to reply