Solved Building Qt 5.9.5 on Windows with -qt-sqlite generates invalid dll (LNK1107: qsqlited.dll invalid)
-
I compiled Qt 5.9.5 from source on Windows with msvc2019, using the following configure command:
configure -prefix C:\Tools\DEV\Qt\5.9.5-debug -qt-sqlite -platform win32-msvc -debug -skip qtwebengine
I found the -qt-sqlite option on this page.
I compile with jom then install with jom install.
I then create a sample project with this CMakeLists.txt linked against this Qt library:
project(test-plugin) cmake_minimum_required(VERSION 3.14) list(APPEND CMAKE_PREFIX_PATH "${Qt5_DIR}") find_package(Qt5 COMPONENTS Core Sql REQUIRED) add_executable(test main.cpp) target_link_libraries(test PRIVATE Qt5::QSQLiteDriverPlugin)
Building
mkdir build && cd build && cmake . . -DQt5_DIR=C:/Tools/DEV/Qt/5.9.5-debug && cmake --build . --config Debug
Output:
Microsoft (R) Build Engine version 16.6.0+5ff7b0c9e pour .NET Framework Copyright (C) Microsoft Corporation. Tous droits réservés. Checking Build System Building Custom Rule C:/Tools/DEV/x479333/ead/test_sql_driver/CMakeLists.txt main.cpp C:\Tools\DEV\Qt\5.9.5-debug\plugins\sqldrivers\qsqlited.dll : fatal error LNK1107: invalid or corrupt file: cannot read at 0x3A0 [C:\Tools\DEV\x479333\ead\test_sql_driver\build\test.vcxproj]
What is the problem here?
One weird thing I found is that in the install directory there is no trace of a qsqlited.lib file, but there is one in the Qt compile directory (C:\Tools\DEV\Qt\qt-everywhere-opensource-src-5.9.5-debug\qtbase\plugins\sqldrivers\qsqlited.lib). Aren't DLL on windows required to have an associated .lib for compilation?
-
You can not mix debug and release libs and you should not deploy debug executables and libraries.
Therefore you have to use qsqlite.dll. -
The Qt sqlite plugin is (as the name says) a plugin and therefore you can't link against it - it's loaded at runtime.
-
Thanks, I see the problem. But isn't it a problem that adding this plugin as a cmake dependency to a target generates this error? Shouldn't it cleanly link with .lib describing the .dll and then load the dll at runtime?
-
@Percee said in Building Qt 5.9.5 on Windows with -qt-sqlite generates invalid dll (LNK1107: qsqlited.dll invalid):
Shouldn't it cleanly link with .lib describing the .dll
No, because then it would be loaded when your app is loaded, not at runtime. Plug-ins are only loaded when needed.
-
Thanks, so from what I understand I have to use QPluginLoader to load it at runtime.
I don't understand what the cmake target is there for though. Is there a way to leverage the cmake target to make it install the DLL? Currently I call windeployqt, but I'm not sure it can detect this can of dependencies.
-
@Percee said in Building Qt 5.9.5 on Windows with -qt-sqlite generates invalid dll (LNK1107: qsqlited.dll invalid):
Thanks, so from what I understand I have to use QPluginLoader to load it at runtime.
Why? Simply use QSqlDatabase and you're fine...
I don't understand what the cmake target is there for though.
Because someone might need it
Currently I call windeployqt, but I'm not sure it can detect this can of dependencies.
It simply copies all plugins of a given type when you use e.g. QtSql
-
So I tried using QSqlDatabase + windeployqt. Here is my code:
#include <QSqlDatabase> #include <QCoreApplication> int main(int argc, char**argv) { QCoreApplication app(argc, argv); QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName(":memory:"); }
I compile it and call windeployqt on the executable, which adds Qt5Cored.dll, Qt5Sql.dll and a translation directory.
When I run the executable I get:QSqlDatabase: QSQLITE driver not loaded QSqlDatabase: available drivers:
I tried copying the file qsqlited.dll next to the exe but this doesn't change anything.
What am I doing wrong?
EDIT: when I put it in plugins/sqldrivers it works. But why does windeployqt does not do that for me?
-
@Percee said in Building Qt 5.9.5 on Windows with -qt-sqlite generates invalid dll (LNK1107: qsqlited.dll invalid):
I tried copying the file qsqlited.dll next to the exe but this doesn't change anything.
It must be in the plugins folder as explained in the documentation.
Does windeployqt use the correct Qt path where the sqlite plugin is under <QTDIR>/plugins/sqldrivers?
-
When I manually copy the plugins/sqldrivers dir next to the exe, there is no more error of no drivers available. Now I just want windeployqt to do that for me.
My Qt install does have a QT_DIR/plugins/sqldrivers dir, and when I call windeployqt I make sure to set the front of %PATH% to QT_DIR/bin, as stated in the help. But still windeployqt does not deploy it.
-
@Percee said in Building Qt 5.9.5 on Windows with -qt-sqlite generates invalid dll (LNK1107: qsqlited.dll invalid):
It works when I put it in the plugins folder directly.
What do you mean?
-
I edited my message so it's clearer (I have 10 min cooldown between each messages)
-
windeployqt has two options which you should check -
--verbose
and--plugindir
-
Thanks. I added the --debug option also. But here is the output (my path points to a QT_DIR/bin install which contains ONLY debug qt):
C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug>windeployqt --debug test.exe --verbose 4 Qt binaries in C:\Tools\DEV\Qt\5.9.5-debug\bin readPeExecutable: C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\test.exe 64 bit, dependent libraries: Qt5Sqld.dll Qt5Cored.dll VCRUNTIME140_1D.dll VCRUNTIME140D.dll ucrtbased.dll KERNEL32.dll, release readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\bin\Qt5Sqld.dll 64 bit, dependent libraries: Qt5Cored.dll KERNEL32.dll VCRUNTIME140D.dll ucrtbased.dll readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\bin\Qt5Cored.dll 64 bit, dependent libraries: MPR.dll VERSION.dll WS2_32.dll KERNEL32.dll USER32.dll SHELL32.dll ole32.dll ADVAPI32.dll WINMM.dll MSVCP140D.dll VCRUNTIME140D.dll VCRUNTIME140_1D.dll ucrtbased.dll C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\test.exe 64 bit, debug executable readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\bin\Qt5Cored.dll 64 bit, dependent libraries: MPR.dll VERSION.dll WS2_32.dll KERNEL32.dll USER32.dll SHELL32.dll ole32.dll ADVAPI32.dll WINMM.dll MSVCP140D.dll VCRUNTIME140D.dll VCRUNTIME140_1D.dll ucrtbased.dll readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\plugins\sqldrivers\qsqlited.dll 64 bit, debug readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\plugins\sqldrivers\qsqlodbcd.dll 64 bit, debug readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\plugins\sqldrivers\qsqlited.dll 64 bit, dependent libraries: Qt5Sqld.dll Qt5Cored.dll KERNEL32.dll VCRUNTIME140D.dll ucrtbased.dll readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\bin\Qt5Sqld.dll 64 bit, dependent libraries: Qt5Cored.dll KERNEL32.dll VCRUNTIME140D.dll ucrtbased.dll readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\bin\Qt5Cored.dll 64 bit, dependent libraries: MPR.dll VERSION.dll WS2_32.dll KERNEL32.dll USER32.dll SHELL32.dll ole32.dll ADVAPI32.dll WINMM.dll MSVCP140D.dll VCRUNTIME140D.dll VCRUNTIME140_1D.dll ucrtbased.dll readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\plugins\sqldrivers\qsqlodbcd.dll 64 bit, dependent libraries: Qt5Sqld.dll Qt5Cored.dll ODBC32.dll KERNEL32.dll VCRUNTIME140D.dll ucrtbased.dll readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\bin\Qt5Sqld.dll 64 bit, dependent libraries: Qt5Cored.dll KERNEL32.dll VCRUNTIME140D.dll ucrtbased.dll readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\bin\Qt5Cored.dll 64 bit, dependent libraries: MPR.dll VERSION.dll WS2_32.dll KERNEL32.dll USER32.dll SHELL32.dll ole32.dll ADVAPI32.dll WINMM.dll MSVCP140D.dll VCRUNTIME140D.dll VCRUNTIME140_1D.dll ucrtbased.dll Direct dependencies: Qt5Core Qt5Sql All dependencies : Qt5Core Qt5Sql To be deployed : Qt5Core Qt5Sql Plugins: C:/Tools/DEV/Qt/5.9.5-debug/plugins/sqldrivers/qsqlited.dll,C:/Tools/DEV/Qt/5.9.5-debug/plugins/sqldrivers/qsqlodbcd.dll Checking C:/Tools/DEV/Qt/5.9.5-debug/bin/Qt5Coredd.dll, C:/Tools/DEV/x479333/ead/test_sql_driver/build/Debug/Qt5Coredd.dll C:\Tools\DEV\Qt\5.9.5-debug\bin\Qt5Coredd.dll does not exist.
The last line you can see is trying to copy Qt5Coredd.dll. The command stops there, nothing gets copied at all next to my executable. Why is that? Because of my --debug option? Without --debug windeployqt tries to copy the release version of qsqlite.dll, which doesn't exist. But with --debug it tries to copy a Qt5Coredd.dll which doesn't exist either.
EDIT: here is the output without the --debug option
C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug>windeployqt --verbose 4 test.exe Qt binaries in C:\Tools\DEV\Qt\5.9.5-debug\bin readPeExecutable: C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\test.exe 64 bit, dependent libraries: Qt5Sqld.dll Qt5Cored.dll VCRUNTIME140_1D.dll VCRUNTIME140D.dll ucrtbased.dll KERNEL32.dll, release readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\bin\Qt5Sqld.dll 64 bit, dependent libraries: Qt5Cored.dll KERNEL32.dll VCRUNTIME140D.dll ucrtbased.dll readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\bin\Qt5Cored.dll 64 bit, dependent libraries: MPR.dll VERSION.dll WS2_32.dll KERNEL32.dll USER32.dll SHELL32.dll ole32.dll ADVAPI32.dll WINMM.dll MSVCP140D.dll VCRUNTIME140D.dll VCRUNTIME140_1D.dll ucrtbased.dll C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\test.exe 64 bit, release executable readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\bin\Qt5Cored.dll 64 bit, dependent libraries: MPR.dll VERSION.dll WS2_32.dll KERNEL32.dll USER32.dll SHELL32.dll ole32.dll ADVAPI32.dll WINMM.dll MSVCP140D.dll VCRUNTIME140D.dll VCRUNTIME140_1D.dll ucrtbased.dll readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\plugins\sqldrivers\qsqlited.dll 64 bit, debug readPeExecutable: C:\Tools\DEV\Qt\5.9.5-debug\plugins\sqldrivers\qsqlodbcd.dll 64 bit, debug Direct dependencies: Qt5Core Qt5Sql All dependencies : Qt5Core Qt5Sql To be deployed : Qt5Core Qt5Sql Plugins: Checking C:/Tools/DEV/Qt/5.9.5-debug/bin/Qt5Cored.dll, C:/Tools/DEV/x479333/ead/test_sql_driver/build/Debug/Qt5Cored.dll Updating Qt5Cored.dll. Checking C:/Tools/DEV/Qt/5.9.5-debug/bin/Qt5Sqld.dll, C:/Tools/DEV/x479333/ead/test_sql_driver/build/Debug/Qt5Sqld.dll Updating Qt5Sqld.dll. Checking C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/redist/MSVC/14.26.28720/vc_redist.x64.exe, C:/Tools/DEV/x479333/ead/test_sql_driver/build/Debug/vc_redist.x64.exe Updating vc_redist.x64.exe. Patching Qt5Cored.dll... Creating C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations... Creating qt_ar.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_ar.qm qtbase_ar.qm Creating qt_bg.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_bg.qm qtbase_bg.qm Creating qt_ca.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_ca.qm qtbase_ca.qm Creating qt_cs.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_cs.qm qtbase_cs.qm Creating qt_da.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_da.qm qtbase_da.qm Creating qt_de.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_de.qm qtbase_de.qm Creating qt_en.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_en.qm qtbase_en.qm Creating qt_es.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_es.qm qtbase_es.qm Creating qt_fi.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_fi.qm qtbase_fi.qm Creating qt_fr.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_fr.qm qtbase_fr.qm Creating qt_gd.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_gd.qm qtbase_gd.qm Creating qt_he.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_he.qm qtbase_he.qm Creating qt_hu.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_hu.qm qtbase_hu.qm Creating qt_it.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_it.qm qtbase_it.qm Creating qt_ja.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_ja.qm qtbase_ja.qm Creating qt_ko.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_ko.qm qtbase_ko.qm Creating qt_lv.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_lv.qm qtbase_lv.qm Creating qt_pl.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_pl.qm qtbase_pl.qm Creating qt_ru.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_ru.qm qtbase_ru.qm Creating qt_sk.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_sk.qm qtbase_sk.qm Creating qt_uk.qm... Running: lconvert -o C:\Tools\DEV\x479333\ead\test_sql_driver\build\Debug\translations\qt_uk.qm qtbase_uk.qm
You can see that "Plugins:" is empty without --debug. Even if I add --plugindir plugins, a directory named plugins get created but it is empty.
-
You can not mix debug and release libs and you should not deploy debug executables and libraries.
Therefore you have to use qsqlite.dll. -
Ok thank you, all my questions are answered.