在Linux上使用动态链接为Windows交叉编译Qt应用程序

14

为了遵守Qt的LGPL许可证,使用Qt库的应用程序必须将源代码公开或者动态链接Qt库(如果我在这几句话中理解正确的话)。

因此,我想创建一个闭源应用程序,正是这样做的。此外,我想使用支持C++11的g++/MinGW在Linux上进行开发(当前为Xubuntu 12.04),以创建Windows二进制文件。我按照这篇有用的指南完成了后者。但正如该指南所述,它创建的是静态链接的可执行文件。

由于我使用MXE自动下载和构建了Qt库(版本5.0),我没有太多机会影响过程。所以我的问题是,如何创建Qt库和相应应用程序的动态链接版本?


一个问题:为什么不在Windows上使用mingw?我认为Linux上的mingw交叉编译器可以像在Windows上一样支持C++11。 - Min Lin
@MinLin 对我来说,原因是 Linux 环境更加舒适。 - tshepang
4个回答

10

更新

现在,使用MXE构建库的首选方式是为工具链指定“shared”选项以构建动态版本:

make MXE_TARGETS=i686-w64-mingw32.shared qt5

译文:

编辑:我创建了一个Git存储库,在其中对MXE进行了所有必要的更改,以构建Qtbase的共享版本。可以在https://github.com/jeremysalwen/mxe上获取。要构建,请克隆存储库,然后运行“make qtbase”。 我以下保留原始帖子。

所以我下载了MXE环境,看起来编译Qt使用的代码都在src/qt.mk中。

基本的过程是将此代码与构建Qt的标准指令相匹配。如果您查看qt.mk和qtbase.mk内部,您会发现它实际上非常简单,基本上只运行./configure,make,然后安装生成的文件。如果您能够理解这一点,您应该能够匹配构建Qt静态/动态版本的指令,并修改qt.mk,使其与动态指令相匹配。

无论如何,我认为我已经找到了问题所在。看起来区别在于编译Qt时使用了“-static”标志。因此,如果我们简单地删除传递给qt.mk和qtbase.mk中的./configure的“-static”标志,则我期望MXE将构建一个动态Qt版本。当然,您可能需要更改其他内容,但希望这就是您需要做的全部。


@Tshepang:我已经在Github上创建了一个存储库,对qtbase及其所有依赖项的构建脚本进行了必要的更改。我已经在我的帖子中添加了一个链接。 - Jeremy Salwen
构建很顺利,我的应用程序也是如此;现在我只需要弄清楚如何将其打包并在Windows上运行。 - tshepang
1
同样的问题,到目前为止非常感谢你。在Windows上运行编译后的应用程序时,首先缺少dll文件(当然),但是当复制所需的文件后,我只得到了一个运行时错误。我会进一步调查这个问题。 - Ratatwisker
我不确定下一步该怎么做。我看到有一堆下载可用,标记为MinGW 4.7的可能是正确的。我只需要安装它,一切都会好吗?这是你尝试过的吗@Ratatwisker?我害怕下载它,只发现它不起作用(它太大了,超过800MB)。 - tshepang
1
我尝试了MinGW软件包中的库以及mxe构建中的库(位于<mxe>/usr/i686-pc-mingw32/qt5/lib/)。无论哪种方式,在尝试运行编译后的应用程序时都会产生相同的消息:“此应用程序已请求运行时以不寻常的方式终止。”使用Visual Studio调试器,我可以看到两条消息,提示“传递给C运行时函数的参数无效”。下一步我想尝试的是在调试模式下编译Qt和应用程序,但我没有时间这样做。 - Ratatwisker

5

首先您需要安装Wine。

sudo apt-get install wine

接着下载Qt5 Windows MinGW SDK,使用wine运行。

wget http://releases.qt-project.org/qt5/5.0.1/qt-windows-opensource-5.0.1-mingw47_32-x86-offline.exe
wine qt-windows-opensource-5.0.1-mingw47_32-x86-offline.exe

跟随向导安装Qt。 然后
cd ~/.wine/drive_c/Qt/Qt5.0.1/Tools/QtCreator/bin
wine qtcreator.exe

我尝试了qtcreator的示例,它在linux下编译和运行都很好,在将可执行文件复制到已设置Qt的Windows机器上时,它也可以正常运行。
当然,缺点之一是你不会像使用本机qtcreator和编译器那样自然。我不知道它与本机Linux二进制文件相比慢多少,但如果你的项目很大,jom是可用的,并且您可以利用多个核心进行编译。
要在qtcreator中使用jom而不是make,请在这里进行修改。
projects > Build & Run > Build > Build Steps > Make

替换为jom,并添加make参数-j N,其中N是您想要使用的核心数量。


什么是 jom,名字中的 offline 是什么意思? - tshepang
2
jom相当于make,用jom替换make。-j N将启动N个并行进程来构建您的项目。离线只是QtSDK安装程序的名称,我认为它意味着安装程序拥有您所需的一切,并且能够在您没有互联网连接时安装qt。 - Min Lin

2

最近我在这方面遇到了些困难,但是通过使用octave的mxe分支(链接),我取得了一些成功。他费了很大劲儿来构建支持共享(.dll)库的qt,满足了我的需求。这里有一个他发布的帖子链接


1
你需要为动态链接构建QT。如果你已经为静态链接(通常是Linux中的.a文件)构建了QT,则你的二进制文件将是静态的。如果你在Linux上构建共享对象文件(.so),则你的二进制文件将是动态链接的。你还需要在应用程序中包含相关的.dll文件,以便当其他人运行可执行文件时,它可以访问这些库。

qt-project.org的QT SDK包括动态链接文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接