Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Failing to load QODBC3 driver on Mac OS X Mojave



  • Hello guys,
    I've been recently trying to connect to MS SQL Server using Qt 5.14.1.
    My current OS is Mac OS X Mojave 10.14.6

    After I built ODCB driver I get an error message while running the project:
    //
    objc[13030]: Class QMacAutoReleasePoolTracker is implemented in both /Users/md/Qt/5.14.1/clang_64/lib/QtCore.framework/Versions/5/QtCore (0x101d21030) and /Users/md/Qt/5.14.1/clang_64/plugins/sqldrivers/libqsqlodbc.dylib (0x10608e6c8). One of the two will be used. Which one is undefined.
    objc[13030]: Class QT_ROOT_LEVEL_POOL__THESE_OBJECTS_WILL_BE_RELEASED_WHEN_QAPP_GOES_OUT_OF_SCOPE is implemented in both /Users/md/Qt/5.14.1/clang_64/lib/QtCore.framework/Versions/5/QtCore (0x101d210a8) and /Users/md/Qt/5.14.1/clang_64/plugins/sqldrivers/libqsqlodbc.dylib (0x10608e740). One of the two will be used. Which one is undefined.
    objc[13030]: Class KeyValueObserver is implemented in both /Users/md/Qt/5.14.1/clang_64/lib/QtCore.framework/Versions/5/QtCore (0x101d210d0) and /Users/md/Qt/5.14.1/clang_64/plugins/sqldrivers/libqsqlodbc.dylib (0x10608e768). One of the two will be used. Which one is undefined.
    objc[13030]: Class RunLoopModeTracker is implemented in both /Users/md/Qt/5.14.1/clang_64/lib/QtCore.framework/Versions/5/QtCore (0x101d21120) and /Users/md/Qt/5.14.1/clang_64/plugins/sqldrivers/libqsqlodbc.dylib (0x10608e7b8). One of the two will be used. Which one is undefined.
    QObject::moveToThread: Current thread (0x7fdd61c03af0) is not the object's thread (0x7fdd61e89900).
    Cannot move to target thread (0x7fdd61c03af0)

    You might be loading two sets of Qt binaries into the same process. Check that all plugins are compiled against the right Qt binaries. Export DYLD_PRINT_LIBRARIES=1 and check that only one set of binaries are being loaded.
    QSqlDatabase: QODBC3 driver not loaded
    QSqlDatabase: available drivers: QSQLITE QODBC QODBC3 QPSQL QPSQL7
    Error "Driver not loaded Driver not loaded"
    //

    the isDriverAvailable("QODBC3") return TRUE

    I've installed unixODBC and FreeTDS. Then I built ODCB doing:
    PathToQt/5.14.1/clang_64/bin/qmake "INCLUDEPATH+=/usr/local/unixODBC/include" "LIBS+=-L/usr/local/unixODBC/lib -lodbc" odbc.pro
    Than running make and than make install.
    Everything seemed to be okay... No errors occurred.

    My c++ code. I know it may be not correc:

    db = QSqlDatabase::addDatabase("QODBC3");
    db.setConnectOptions();
    
    QString dns = QString("DRIVER={SQL Native Client};SERVER=%1;DATABASE=%2;Trusted_Connection=Yes;").arg("localhost").arg("QtTestDataBase");
    db.setDatabaseName(dns);
    
    if (!db.open()) {
        qDebug() << "Error" << db.lastError().text();
        return;
    }
    

    So the Error printed with qDebug() is: "Driver not loaded Driver not loaded"

    Maybe I should try reinstalling Qt?

    I would appreciate your help, guys. Thank you.



  • Hi, don't think you need to reinstall anything, but it is a bit tricky to get ODBC up and running on a Mac, Luckily this has been covered before on this forum, for example this answer is very useful.

    I just tested on a brand new Mac, with MacOS 10.15.4. First I installed Homebrew and Qt 5.14.1, then, as you did, the mandatory rebuild of Qt's ODBC plugin (so that it uses unixodbc and not iodbc). I followed the forum answer above, here is my version for Qt 5.14.1 (which is installed in the default place ~/Qt):

    $ brew install freeTDS
    $ cd ~/Qt/5.14.1/Src/qtbase/src/plugins/sqldrivers
    $ sed -i -e 's/-liodbc/-lodbc/' configure.json
    $ ~/Qt/5.14.1/clang_64/bin/qmake -- ODBC_PREFIX=/usr/local/Cellar/unixodbc/2.3.7
    $ make sub-odbc
    $ cp plugins/sqldrivers/libqsqlodbc.dylib ~/Qt/5.14.1/clang_64/plugins/sqldrivers
    

    Then I started an MSSQLServer on 192.168.1.100 and tested with a Qt console program, here is the .pro file:

    QT -= gui
    QT += sql
    CONFIG += c++11 console
    CONFIG -= app_bundle
    SOURCES += main.cpp
    

    and here is the main.cpp:

    #include <QCoreApplication>
    #include <QTextStream>
    #include <QDir>
    #include <QtSql/QSqlDatabase>
    #include <QtSql/QSqlRecord>
    #include <QtSql/QSqlError>
    #include <QSqlQuery>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
    // try to load the SQL ODBC plugin
        auto db = QSqlDatabase::addDatabase("QODBC3");
        if (!db.isValid())
            qFatal("addDatabase(QODBC) failed :-(");
    
    // prepare the args
        QString sServerIP = "192.168.1.100";
        QString sDatabase = "northwind";
        QString sUsername = "sa";
        QString sPassword = "adminsa";
        
    // setup dummy DSN name and where the freeTDS .so driver file is
        QString sDSN      = "dsn1";
        QString sFilename = "/usr/local/lib/libtdsodbc.so";
    
    // create an .odbc.ini file on our home directory
        QFile fOdbc(QDir::homePath() + "/.odbc.ini");
        if (!fOdbc.open(QFile::WriteOnly | QFile::Text))
            qFatal("open ~/.odbc.ini for write failed");
    
        QTextStream tsOdbc(&fOdbc);
        tsOdbc << "[" << sDSN << "]"           << "\n";
        tsOdbc << "Driver     = " << sFilename << "\n";
        tsOdbc << "Servername = " << sDSN      << "\n";
        tsOdbc << "Database   = " << sDatabase << "\n";
        tsOdbc.flush();
        fOdbc.close();
    
    // create a .freetds.conf file on our home directory
        QFile fFreeTds(QDir::homePath() + "/.freetds.conf");
        if (!fFreeTds.open(QFile::WriteOnly | QFile::Text))
            qFatal("open ~/.freetds.conf for write failed");
    
        QTextStream tsFT(&fFreeTds);
        tsFT << "[" << sDSN << "]"        << "\n";
        tsFT << "host = " <<  sServerIP   << "\n";
        tsFT << "port = 1433"             << "\n";
        tsFT << "tds version = 7.0"       << "\n";
        tsFT.flush();
        fFreeTds.close();
    
        db.setDatabaseName(sDSN);
        if (!db.open(sUsername,sPassword))
            qFatal("open() failed, error = '%s'",qUtf8Printable(db.lastError().text()));
    
        QTextStream cout(stdout);
    
    // party on the db (dump all the customers)
        auto query = QSqlQuery("select * from Customers");
        auto columns = query.record().count();
        while (query.next())
            for (auto c = 0; (c < columns); ++c)
                cout << QString::number(c) << " : " << query.value(c).toString() << "\n";
    
    // that's all folks
        db.close();
    }
    

    and it runs fine and prints all the Northwind db's customers.

    Note: on MacOS it's very difficult to use the kind of databasenames you use (i.e "..DRIVER={SQL Native Client};SERVER=%1;DATABASE=%2;Trusted_Connection=Yes;"), instead I create 2 files: .odbc.ini and .freetds.conf



  • Forgot one thing: for umlaut characters to appear correctly from the Northwind's customers (in the test program above), like these:
    ...
    4 : Berguvsvägen 8
    5 : Luleå
    ...
    you should add a "client charset" line to the .freetds.conf file, like this:

    QTextStream tsFT(&fFreeTds);
    tsFT << "[" << sDSN << "]"       << "\n";
    tsFT << "host = " <<  sServerIP  << "\n";
    tsFT << "port = 1433"            << "\n";
    tsFT << "tds version = 7.0"      << "\n";
    tsFT << "client charset = UTF-8" << "\n";
    

    P.S. I have an old MSSQLServer 2008 R2, if you have a more recent version, you might need to change the "tds version..." in the .freetds.conf file to something higher, like 7.3.



  • @hskoglund First thank you for such a quick reply I appreciate it.
    It might be a stupid question of mine but following your guide I ran into problem at the beginning:

    sqldrivers$ make sub-odbc
    make: *** No rule to make target `sub-odbc'.  Stop.
    

    If I run just "make" I can't find the libqsqlodbc.dylib anywhere
    What does actually "sub-odbc" do?

    I also don't get any Configuration Summary after running qmake script



  • @Mark-Durkot You might have some debris left over from previous builds. To be sure, nuke the whole Src directory and download it again (I use Qt's MaintenanceTool to remove "Sources" and install "Sources" again).
    Now you should have a clean slate, try the "sed.." and "qmake..." steps again, hopefully you'll get a Configuration Summary this time.

    The make sub-odbc command tells make to build the subtarget odbc (and skip the subtarget sqlite).



  • @hskoglund Dear mate, I have to say huge THANK YOU for your help! I'm sorry for taking your time! Finally after reinstalling Sources I got all the terminal commands running perfect and giving no errors! I also successfully connected to my database and was able to read data!

    Tack så mycket (if your are from Sweden) :)



  • @Mark-Durkot Thanks! Sure, I'm native Swedish. Don't worry about the time, last week I got the Corona (the flu, not the beer), felt like an old man for a couple of days, this week I am well again but staying at home. So answering questions on this forum is a great way to stay in touch with the outside world :-)



  • @hskoglund Ohh, I wish you get in a completely fit form as soon as possible (to be able to go get the Corona beer now))) :)



  • @Mark-Durkot No worries, I'm back in business, went looking today for one of these:alt text


Log in to reply