交叉编译Qt 5应用程序(主机:Fedora 19/64位,目标:Windows 32位)后,我执行以下步骤来部署可执行文件:
$ DEST=/windows/testdir
$ cp /usr/i686-w64-mingw32/sys-root/mingw/bin/*.dll $DEST
$ mkdir $DEST/platforms
$ cp /usr/i686-w64-mingw32/sys-root/mingw/lib/qt5/plugins/platforms/qwindows.dll\
$DEST/platforms
$ cp release/main.exe $DEST # the cross-compiled Qt5 binary
我在Windows上测试它是这样的:
say /windows is mounted on f:
start command prompt window
f:
cd testdir
main
我得到了:
无法加载平台插件“windows”。可用的平台是:
Microsoft Visual C ++运行时库 此应用程序已请求Runtime以不寻常的方式终止它。 请联系应用程序的支持团队以获取更多信息。
我真的不相信第一条消息,因为:
a)上述步骤过去(在同一Fedora 19系统上执行)
b)平台目录为documented in the qt docs。
现在该应用程序在对话框中包含了一些PNG / JPG(通过Qt的资源文件系统读取,作为QIcons),发生了变化。
因此,我也复制了一些插件:
$ cp -r /usr/i686-w64-mingw32/sys-root/mingw/lib/qt5/plugins $DEST
这无助于解决上述问题。
有没有办法调试像这样的动态运行时链接器问题?
我可以指示它,以便我以某种方式获得输出,其中应用程序/链接器尝试加载哪个dll以及它的查找位置在哪里? (以及他们失败的原因......)
例如,这样的事情会很棒:
ldd: main.exe -> load of foo.dll in work-dir failed (no such file)
ldd: main.exe -> load of bar.dll in work-dir/platforms failed (wrong file format)
ldd: main.exe -> load of baz.dll in work-dir successful
...
我在Fedora 19上使用以下步骤进行交叉编译:
$ mingw32-qmake-qt5 main.pro -o win32.mf
$ mingw32-make -f win32.mf
$ # -> binary is created in release/main.exe
我看过葡萄酒用于测试目的。它很有用,因为它在找不到DLL时会显示错误消息,例如:
$ wine $DEST/main.exe
err:module:import_dll Library libEGL.dll (which is needed by L"Z:\\usr\\i686-w64-mingw32\\sys-root\\mingw\\lib\\qt5\\plugins\\platforms\\qwindows.dll") not found
err:module:import_dll Library libjpeg-62.dll (which is needed by L"Z:\\usr\\i686-w64-mingw32\\sys-root\\mingw\\lib\\qt5\\plugins\\imageformats\\qjpeg.dll") not found
有趣的是,它直接在Z:\\usr\\i686-w64-mingw32\\sys-root\\mingw\\lib\\qt5\\
下找到了平台库和所需的插件。
但是当/usr/i686-w64-mingw32/sys-root/mingw/bin/*.dll
中所有需要的DLL被复制到$ DEST时,wine运行相同的main.exe
就好了 - 在本机窗口(7)上我得到了上面的错误框。
答案 0 :(得分:0)
您可以使用Dependency Walker之类的工具来检查单个DLL的依赖关系,Wine用于快速检查编译主机上的启动,Process Monitor可以查看在访问期间访问哪些目录/文件过程的运行时间。
从Qt应用程序调试输出库路径也是有意义的,例如
int main(int argc, char **argv)
{
qDebug() << "Library paths: " << QApplication::libraryPaths();
QApplication app(argc, argv);
...
随后我在本机窗口上获得以下输出:
Library paths: ()
(要启用qDebug()语句 - 即使使用发布二进制文件 - 您必须将CONFIG += console
添加到qmake项目文件中。)
查看Process Monitor输出,似乎二进制文件不会尝试在其当前工作目录(CWD)或其基本目录中打开任何插件(平台或其他)。
当我扩展库路径时,二进制文件在其CWD中找到所有需要的插件:
int main(int argc, char **argv)
{
QApplication::addLibraryPath(QDir::currentPath());
QApplication app(argc, argv);
...
我不知道这是否有资格作为解决办法 - 也许应该做一些这样的事情。但Qt documentation似乎暗示相反:
要部署应用程序,我们必须确保将相关的Qt DLL(对应于应用程序中使用的Qt模块)和windows平台插件以及可执行文件复制到release子目录中的同一目录。 / p>
现在完成部署程序:
$ cp /usr/i686-w64-mingw32/sys-root/mingw/bin/*.dll $DEST
# copying platforms, imageformats etc. plugin directories:
$ cp /usr/i686-w64-mingw32/sys-root/mingw/lib/qt5/plugins/* $DEST -r
$ cp release/main.exe $DEST
(根据您在编译主机上安装的软件包,您可能不需要复制所有DLL - 使用wine可以很容易地为所有需要的非插件dll启动修复点迭代。)
缺少非平台插件不一定会中止程序启动 - 例如没有jpeg插件,就会显示一些图标。