c++qtlinkerodbc

How to resolve linking issues when using static QT odbc


I'm currently using Qt 4.7.4 configured with the command lines

-static -debug-and-release -opensource -platform win32-msvc2010 -qt-sql-odbc -qt-sql-sqlite

and after trying re-run an originally working program without the SQL libraries added I receive about 30 linking errors.

1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLGetInfoW@20 referenced in function "public: class QChar __thiscall QODBCDriverPrivate::quoteChar(void)" (?quoteChar@QODBCDriverPrivate@@QAE?AVQChar@@XZ)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLSetConnectAttrW@16 referenced in function "public: bool __thiscall QODBCDriverPrivate::setConnectionOptions(class QString const &)" (?setConnectionOptions@QODBCDriverPrivate@@QAE_NABVQString@@@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLGetDiagRecW@32 referenced in function "class QString __cdecl qWarnODBCHandle(int,void *,int *)" (?qWarnODBCHandle@@YA?AVQString@@HPAXPAH@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLFreeHandle@8 referenced in function "public: virtual __thiscall QODBCResult::~QODBCResult(void)" (??1QODBCResult@@UAE@XZ)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLNumResultCols@8 referenced in function "protected: virtual bool __thiscall QODBCResult::reset(class QString const &)" (?reset@QODBCResult@@MAE_NABVQString@@@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLGetStmtAttrW@20 referenced in function "protected: virtual bool __thiscall QODBCResult::reset(class QString const &)" (?reset@QODBCResult@@MAE_NABVQString@@@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLExecDirectW@12 referenced in function "protected: virtual bool __thiscall QODBCResult::reset(class QString const &)" (?reset@QODBCResult@@MAE_NABVQString@@@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLSetStmtAttrW@16 referenced in function "protected: virtual bool __thiscall QODBCResult::reset(class QString const &)" (?reset@QODBCResult@@MAE_NABVQString@@@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLAllocHandle@12 referenced in function "protected: virtual bool __thiscall QODBCResult::reset(class QString const &)" (?reset@QODBCResult@@MAE_NABVQString@@@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLColAttributeW@28 referenced in function "class QSqlField __cdecl qMakeFieldInfo(class QODBCPrivate const *,int)" (?qMakeFieldInfo@@YA?AVQSqlField@@PBVQODBCPrivate@@H@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLDescribeColW@36 referenced in function "class QSqlField __cdecl qMakeFieldInfo(class QODBCPrivate const *,int)" (?qMakeFieldInfo@@YA?AVQSqlField@@PBVQODBCPrivate@@H@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLFetchScroll@12 referenced in function "protected: virtual bool __thiscall QODBCResult::fetch(int)" (?fetch@QODBCResult@@MAE_NH@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLFetch@4 referenced in function "protected: virtual bool __thiscall QODBCResult::fetchNext(void)" (?fetchNext@QODBCResult@@MAE_NXZ)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLGetData@24 referenced in function "protected: virtual class QVariant __thiscall QODBCResult::data(int)" (?data@QODBCResult@@MAE?AVQVariant@@H@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLRowCount@8 referenced in function "protected: virtual int __thiscall QODBCResult::numRowsAffected(void)" (?numRowsAffected@QODBCResult@@MAEHXZ)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLPrepareW@12 referenced in function "public: virtual bool __thiscall QODBCResult::prepare(class QString const &)" (?prepare@QODBCResult@@UAE_NABVQString@@@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLExecute@4 referenced in function "public: virtual bool __thiscall QODBCResult::exec(void)" (?exec@QODBCResult@@UAE_NXZ)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLBindParameter@40 referenced in function "public: virtual bool __thiscall QODBCResult::exec(void)" (?exec@QODBCResult@@UAE_NXZ)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLCloseCursor@4 referenced in function "public: virtual bool __thiscall QODBCResult::exec(void)" (?exec@QODBCResult@@UAE_NXZ)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLMoreResults@4 referenced in function "protected: bool __thiscall QODBCResult::nextResult(void)" (?nextResult@QODBCResult@@IAE_NXZ)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLDriverConnectW@32 referenced in function "public: virtual bool __thiscall QODBCDriver::open(class QString const &,class QString const &,class QString const &,class QString const &,int,class QString const &)" (?open@QODBCDriver@@UAE_NABVQString@@000H0@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLSetEnvAttr@16 referenced in function "public: virtual bool __thiscall QODBCDriver::open(class QString const &,class QString const &,class QString const &,class QString const &,int,class QString const &)" (?open@QODBCDriver@@UAE_NABVQString@@000H0@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLDisconnect@4 referenced in function "private: void __thiscall QODBCDriver::cleanup(void)" (?cleanup@QODBCDriver@@AAEXXZ)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLGetFunctions@12 referenced in function "public: bool __thiscall QODBCDriverPrivate::checkDriver(void)const " (?checkDriver@QODBCDriverPrivate@@QBE_NXZ)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLEndTran@12 referenced in function "protected: virtual bool __thiscall QODBCDriver::commitTransaction(void)" (?commitTransaction@QODBCDriver@@MAE_NXZ)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLTablesW@36 referenced in function "public: virtual class QStringList __thiscall QODBCDriver::tables(enum QSql::TableType)const " (?tables@QODBCDriver@@UBE?AVQStringList@@W4TableType@QSql@@@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLSpecialColumnsW@40 referenced in function "public: virtual class QSqlIndex __thiscall QODBCDriver::primaryIndex(class QString const &)const " (?primaryIndex@QODBCDriver@@UBE?AVQSqlIndex@@ABVQString@@@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLPrimaryKeysW@28 referenced in function "public: virtual class QSqlIndex __thiscall QODBCDriver::primaryIndex(class QString const &)const " (?primaryIndex@QODBCDriver@@UBE?AVQSqlIndex@@ABVQString@@@Z)
1>QtSqld.lib(qsql_odbc.obj) : error LNK2019: unresolved external symbol _SQLColumnsW@36 referenced in function "public: virtual class QSqlRecord __thiscall QODBCDriver::record(class QString const &)const " (?record@QODBCDriver@@UBE?AVQSqlRecord@@ABVQString@@@Z)

I'm assuming that I'm either not including a library in my linking param, or that I'm not configuring QT correctly.

Anyone have experience with this? Just a heads up, I know that compiling QT as not static is way easier when dealing with SQL plugins, but for now the QT library must be compiled in static form.


Solution

  • Your Qt installation is likely OK. When you use ODBC, the application must be linked with odbc32.lib, though. For that, add the following to your .pro file:

    LIBS += -lodbc32
    

    The reason why you didn't have to do it when using dynamic libraries was that the SQL ODBC plugin .dll was already linked to odbc32. Since it is the executable format (.dll/.exe) that carries such information, and not a static plugin .lib, you have to deal with it yourself.

    To be completely correct, there is a way of embedding linker directives within object files that then are bundled in a .lib, but that's a method that Qt does not utilize as it makes it much harder to reason about the complete set of parameters passed to the linker - some come from the command line, and some would then come from the input objects.