在 32 位 win7 上部署 Qt 应用程序 - 在 Win7 x64 上工作(和编译)
Posted
技术标签:
【中文标题】在 32 位 win7 上部署 Qt 应用程序 - 在 Win7 x64 上工作(和编译)【英文标题】:Deploy Qt app on win7 32-bit - works (and compiles) on Win7 x64 【发布时间】:2014-03-18 20:56:55 【问题描述】:好吧,我花了一天时间寻找解决方案并阅读了所有内容,但我无法部署我的 Qt 应用程序,所以我决定问一下。
我在 VS 2013 Ultimate 中通过 Visual Studio 插件使用 Qt 5.2.1,qt 版本是 msvcr2012。我有 Qt 5.2 的 x86 版本(现在是 Qt 下载页面底部的第 3 个版本)。
我的目标是 Win7 32 位。
我的操作系统是 Windows7 64 位,我正在为 win32
、release
/o2 (max speed)
优化、/MD (dynamic C runtime)
构建应用程序,并链接库:
qtmain.lib
Qt5Core.lib
Qt5Gui.lib
Qt5Widgets.lib
Qt5PlatformSupport.lib //this one is added by me, the others are automatically set with the Qt-AddIn template.
我构建它,并在发布文件夹中放入以下内容:
编辑:由于我的编译器版本,我还分发了 vs2012 dll.s,如您所见。
.../release /plugins /platforms
我已经设置了额外的库路径(只是为了 100% 的机会找到它们):
void registerPluginsDir(QDir& exeDir)
QString pluginsRelPath = "plugins";
QString platformsRelPath = "platforms";
QString pluginsPath = exeDir.absoluteFilePath(pluginsRelPath);
QString platformsPath = QDir(pluginsPath).absoluteFilePath(platformsRelPath);
QStringList pathes = QCoreApplication::libraryPaths();
pathes << pluginsPath;
pathes << platformsPath;
QCoreApplication::setLibraryPaths(pathes);
for (auto i : pathes)
qDebug() << i << "\n";
;
int main(int argc, char *argv[])
QString exePath = QString::fromUtf8(argv[0]);
QFileInfo exeInfo(exePath);
QDir exeDir(exeInfo.absolutePath());
registerPluginsDir(exeDir);
QApplication a(argc, argv);
KeyGenerator w;
w.show();
return a.exec();
;
路径是正确的。使用调试器,我看到它们是从我的应用程序文件夹中加载的,而不是从 Qt 主文件夹中加载的。
使用depends.exe 我检查了所有内容。我只收到 2 个警告,没有错误:
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.
我已经根据在 Visual Studio 中调试应用程序时加载的 .dll-s 复制了 .dll-s。 depends.exe 和 debug 之间的唯一区别是,在 VS 系统中 dll-s 是从 SysWOW64 加载的,而不是 system32。
所有这些都在我的(开发者)电脑上运行没有任何错误,但在测试(在 Microsoft Virtual PC 上运行的 Win7 32 位)电脑上我得到了“臭名昭著”的错误:
Failed to load platform plugin “windows”. Available platforms are:
(and here there are the full pathes to the .dll-s,
eg: D:\cproj\keygen\win32\Release\plugins\platforms\qwindows.dll, so it must have found them.
我也关注了这个:http://qt-project.org/wiki/Deploy_an_Application_on_Windows. 重命名 Qt-dir,控制台仅将发布文件夹输出为库输入(而不是像我的第一个测试那样的 Qt 文件夹)。它从应用程序文件夹中加载了 dll-s,启动良好。但是,在我的虚拟 PC 或我兄弟的 pac(Win7 32 位)上,它给了我错误。ˇ关于此的图片:
如何在 32 位机器上运行它?我对每个版本都进行了尝试,release-win32,debug-win32,它们都不起作用。我无法在更多机器上测试它,在 XP 上它甚至无法加载 C 运行时,但这不是目标平台。
更多信息请评论。
编辑:目标 pc 上的 Dependency walker 显示与开发 pc 上的相同。它仍然可以找到插件,但无法加载。
【问题讨论】:
“我知道即使它们是'静态'库”那些被称为import libraries。 感谢您澄清这一点。那是我没有完全理解的。 【参考方案1】:我不知道您为什么要设置路径等。您链接的 Qt wiki 文章显示您没有 plugins
文件夹,但该文件夹中的所有内容都应放入可执行文件的文件夹中。
他们给出的建议很简单:
Qt 的bin
目录中的每个.dll
都需要复制到可执行文件的文件夹中。
Qt 的plugins
和qml
文件夹中的所有内容(文件和文件夹)都需要复制到可执行文件的文件夹中。
然后您可以将其缩减为您不使用的模块。对我有用,很好。
说“我必须将 .dll-s 添加到发布版本,因为我没有使用商业版本”也是不正确的。如果您follow my advice,您可以轻松地使用 Qt 5 和 MSVC 2012 构建静态链接的可执行文件,我什至会详细介绍如何针对 Windows XP 进行所有这些操作。根据 LGPL 条款,您可以做到这一点,您只需要让您的用户重新链接您的项目(这并不意味着提供 C++ 源代码!)。
【讨论】:
部署静态链接的任何东西都是一个糟糕的主意。 不工作,和上一个一样。当我在我的 PC (win7 x64) 上运行时,它会在此文件夹中找到所有内容,但在虚拟机或其他 Win7 x86 上它发现它们也无法加载。 @user3427419 为什么?它允许大量的全局优化,并产生一个单一的可执行文件,总的来说,它小于动态链接的可执行文件,它旁边有所有依赖项。在 Windows 上,这几乎是必须的,除非你喜欢臃肿的安装程序。任何人都不太可能运行其他二进制兼容版本的 Qt 以便共享 dll。当然,在带有包管理器的 Unix 系统上,情况就完全不同了——除非你想预先阻止一些逆向工程;那么静态链接仍然是个好主意。 我终于解决了。检查我的回答,谢谢你的回答! 关于静态链接,首先是安全。如果您使用静态链接,用户很难修补 3rd 方代码中的关键问题,例如 Qt 或 webkit 或 openssl 或其他一些库(如 MSVC 运行时)。哎呀,更糟糕的是,他们很可能甚至无法知道存在问题!至于性能,这不是长期不使用动态链接的正当理由。关于大小,带有 webkit、runtime redist、openssl 的 Qt 应用程序的安装程序小于 10MB。对上面提到的安全隐患争论几 MB 的磁盘空间是不值得的。【参考方案2】:问题不在于插件,但它还请求了 VS2010 的 redist。 在我尝试了一切之后,我在 Qt 文件夹中找到了它,并尝试通过安装它来运行我的应用程序。现在它也可以在 Virtual PC 上运行,但是,它没有在依赖项中列出(或者我监督了它)。它只列出了 2012 和 2013 版本。
【讨论】:
你似乎把事情搞混了。我现在注意到,在您声称“VS 2013 Ultimate 中的 Visual Studio 插件,qt 版本是 msvcr2012”的问题中。您绝对不能将为一个 msvc 构建的 qt 与另一个 msvc 混合。如果您为 MSVC2012 使用预构建的 Qt,它将无法与任何 但 MSVC2012 正常工作。您似乎需要 MSVC2010 可再发行组件来为 msvc2012 运行 Qt,这一事实说明某些事情是非常错误的。您应该只需要用于编译 Qt 的编译器的可再发行组件,并且您应该使用相同的编译器来构建您的应用程序! 如果你想使用msvc2013,你需要先编译Qt,因为msvc2013没有预建的Qt。只有这样才能使用它构建您的应用程序。它可以正常工作,而且除了 msvc2013 之外,您不需要任何 VC 可再发行组件。 如果我发送Qt版本的C运行时我也可以使用它,我唯一不明白的是2010包的用途,因为我下载了2012版本。现在深入研究依赖walker。但是,是的,重新编译它是个好主意。 "如果我发送 Qt 版本的 C 运行时也可以使用它" 不,你不能。事情将被巧妙地破坏,它没有正确部署的事实只是冰山一角。如果您已经为 MSVC2012 下载了预构建的 Qt,您必须将它与 MSVC2012 一起使用。如果您想将 Qt 与 MSVC2013 一起使用,您必须自己构建它,因为目前没有用于 MSVC2013 的预构建二进制文件。这不仅仅是一个好主意。否则它将无法正常工作。我的意思是,拜托,你已经表明它不起作用,争论它没有意义。以上是关于在 32 位 win7 上部署 Qt 应用程序 - 在 Win7 x64 上工作(和编译)的主要内容,如果未能解决你的问题,请参考以下文章
在 Windows 上部署 Qt (C++/QML) 应用程序