不同Ubuntu版本之间能否实现交叉编译?
不同Ubuntu版本之间能否实现交叉编译?
当然可以!而且这正是解决你这种跨Ubuntu版本Qt编译兼容性问题的绝佳方案——不用折腾VM,不用远程编译,在你的Ubuntu 22.04开发机上就能搞定。我来给你分享两种最实用的方法:
方法一:用Chroot环境隔离编译(首推!)
Chroot是一种轻量级的系统隔离方案,相当于在你的主系统里创建一个“迷你版”的目标Ubuntu系统,完全不会污染你的开发环境。我平时给客户做跨版本Qt编译时,最常用的就是这个方案,步骤如下:
- 先安装必要工具:
sudo apt install schroot debootstrap - 为目标版本创建一个目录,比如针对Ubuntu 20.04(代号focal):
sudo mkdir -p /srv/chroot/focal - 用debootstrap初始化这个迷你系统:
sudo debootstrap focal /srv/chroot/focal http://archive.ubuntu.com/ubuntu/ - 配置schroot,让你能直接登录这个环境:
在/etc/schroot/chroot.d/下新建focal.conf文件,内容写:
记得把“你的用户名”换成你实际的系统用户名。[focal] description=Ubuntu 20.04 LTS 编译环境 directory=/srv/chroot/focal users=你的用户名 groups=sudo,users root-users=你的用户名 type=directory - 进入这个隔离环境:
进去后你会发现自己仿佛在一个全新的Ubuntu 20.04系统里了!schroot -c focal - 安装Qt开发依赖和编译器:
sudo apt update && sudo apt install build-essential qt5-default qt5-qmake qtbase5-dev - 把你的Qt代码复制到chroot里(或者直接挂载主系统的代码目录,比如
mount --bind /home/你的用户名/code /home/你的用户名/code),然后正常用qmake或cmake编译就行——出来的二进制就是完全兼容Ubuntu 20.04的!
你可以给每个目标版本都建一个chroot环境,比如21.04(hirsute),步骤完全一样,只是把代号换成对应的就行。
方法二:用APT多版本仓库直接编译(适合简单场景)
如果你不想搞chroot,也可以直接在主系统里安装目标版本的库,但要注意避免依赖冲突:
- 编辑
/etc/apt/sources.list,添加目标版本的源,比如Ubuntu 20.04的:deb http://archive.ubuntu.com/ubuntu/ focal main universe restricted multiverse deb-src http://archive.ubuntu.com/ubuntu/ focal main universe restricted multiverse - 设置源优先级,防止目标版本的包覆盖主系统的包:
在/etc/apt/preferences.d/新建focal-pin文件,内容:
这个优先级设为100,意味着只有明确指定安装focal版本的包时才会用它。Package: * Pin: release n=focal Pin-Priority: 100 - 安装目标版本的Qt库和头文件:
sudo apt update && sudo apt install qt5-default:amd64/focal qtbase5-dev:amd64/focal - 编译时指定使用这些目标版本的库:
比如用qmake的时候,可以手动指定库和头文件路径:
或者用cmake时设置qmake QMAKE_INCDIR=/usr/include/x86_64-linux-gnu/qt5 QMAKE_LIBDIR=/usr/lib/x86_64-linux-gnu/qt5CMAKE_PREFIX_PATH指向目标版本的Qt安装目录。
额外注意事项
- 一定要确保编译时用的Qt版本和目标机器上的版本尽量一致,比如目标机器是Ubuntu 20.04自带的Qt 5.12,那你在chroot里就装Qt 5.12,不要用主系统的Qt 5.15,否则还是会有兼容性问题。
- 编译完成后,可以用
ldd 你的应用程序命令检查依赖,确认链接的是目标版本的库(比如chroot里的路径,或者focal版本的库文件)。 - 如果要给客户打包成deb包,直接在chroot环境里用
checkinstall或者dpkg-deb打包,生成的包会自动带对目标系统的依赖,客户安装起来毫无问题。
这样一来,你不用升级任何远程机器,也不用在VM里写代码,就能轻松为不同Ubuntu版本编译兼容的Qt程序啦!
备注:内容来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

