因项目需要,可能有不同版本的qt程序要运行到同一台机器上,本次实验是qt4.8.5和qt5.3.1开发的程序同时运行在同一台机器上,此机器可以不按照qt的任何版本,当然,两个版本开发的qt与机器的位数必须一样,例如都是32位或者64位。

两个版本的qt的程序我都采用动态编译(静态编译方法请度娘),所以需要把运行程序所需的动态库放到程序可以链接的地方,程序可以链接的动态库路径参见:linux动态库搜索路径。此处直接贴出结论:动态库的搜索路径搜索的先后顺序是:

  1.编译目标代码时指定的动态库搜索路径;

  2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

  3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;

  4.默认的动态库搜索路径/lib;

  5.默认的动态库搜索路径/usr/lib。

考虑到一台机器要运行多个不同版本的qt,而且不能要求机器一定会安装了某个版本的qt,所以不同qt版本的程序所需的动态库最好是放在编译目标代码指定的动态库路径,做到路径独立,因为如果把动态库放在/lib和/usr/lib的话,那么其他版本的qt程序也会到这个地方搜索动态库,可能出现冲突。故此,我这里qt4.8.5和qt5.3.1的程序都在编译时指定动态库路径为工程所在目录下面的lib。

一、对于qt4.8.5具体操作如下:

1)修改工程文件(.pro文件),加上一行LIBS += -L./lib,注意,-L后面不能有空格,要紧跟你指定的动态库路径(可以自由指定),然后保存文件。

2)在终端去到你工程所在目录,执行命令qmake xxx.pro,其中xxx.pro是你的工程文件,命令执行完毕后生成Makefile,用vi或者其他工具打开Makefile,然后搜索LIBS,可以看到,我们这里的LIBS已经加上了你刚才在.pro文件里面配置的./lib,具体如图(图中的-L./lib)所示:

3)执行make得到可执行文件xxx。

测试方法:通过ldd命令查看xxx依赖的动态库指向哪里,命令如下:

ldd untitled | grep -i qt, #这里的untitled为刚才make出来的可执行文件

命令执行结果为:

libQtGui.so.4 => /usr/local/Trolltech/Qt-4.8.5/lib/libQtGui.so.4 (0x00007f289a88e000)
libQtCore.so.4 => /usr/local/Trolltech/Qt-4.8.5/lib/libQtCore.so.4 (0x00007f289a3a0000),

可见此时编译出来的可执行文件的动态库是指向/usr/local/Trolltech/Qt-4.8.5/lib/,这个路径为qt的安装路径,个人猜测是你用qtCreator编写qt程序时就已经默认加上这个动态库搜索路径的,这是qtCreator已经配置了这个路径,具体见qtCreator的Tools-->Options-->Build & Run-->Kits-->Qt Version.

首先我们把这些依赖的库拷贝到我们的可执行文件的同级目录的lib下,首先用终端去到我们的qt工程所在目录,执行命令如下:

mkdir lib    #创建lib目录,目录名必须要与我们在pro文件新增的LIBS += -L后面指定的目录名称一致

cp /usr/local/Trolltech/Qt-4.8.5/lib/libQtGui.so.4 ./lib  #把依赖的库拷贝到lib里面

cp /usr/local/Trolltech/Qt-4.8.5/lib/libQtCore.so.4 ./lib

我们通过屏蔽当前可执行文件指向的动态库路径模拟一个没有安装qt的机器,执行命令如下:

cd /usr/local/Trolltech/Qt-4.8.5;mv lib lib-bak,

这样把lib改名后,我们重新执行了ldd untitled | grep -i qt,命令的结果如下:

libQtGui.so.4 => ./lib/libQtGui.so.4 (0x00007f89a6631000)
libQtCore.so.4 => ./lib/libQtCore.so.4 (0x00007f89a6142000),

可见此时的可执行文件可以自动把动态库路径指向我们编译时执行的./lib,运行可执行文件正常。

最终,我们发布文件时,要把lib拷贝到可执行文件的当前目录,同时把所需的库拷贝到lib里面,把可执行文件和lib一起发布即可。

二、对于qt5.3.1:

这里我采用与qt4.8.5一样的方法,在工程文件所在目录创建lib目录,然后在.pro文件加上LIBS += ./lib,然后重新qmake xxx.pro,然后make,然后ldd xxx | grep -i qt,然后,命令执行结果的所有so文件拷贝到工程文件所在目录的lib里面,然后屏蔽掉ldd xxx | grep -i qt命令执行结果的qt安装路径里面对应的lib,即把这个对应的lib改个名字,然后运行我们的make出来的可执行程序,然后提示错误,error while loading shared libraries: libQt5Widgets.so.5: cannot open shared object file: No such file or directory,然后我用ldd查看动态库链接情况,ldd version531 | grep -i qt,(version531为make出来的可执行程序),结果如下:

libQt5Widgets.so.5 => not found
    libQt5Gui.so.5 => not found
    libQt5Core.so.5 => not found
但是我查看工程目录所在目录的lib,里面是有这几个文件的,不过是一个软连接,但是这个软连接所链接的文件我也已经拷贝在lib里面的,不知道为什么还是提示找不到,没办法,我只有通过环境变量LD_LIBRARY_PATH指定动态库搜索路径到lib了,执行如下命令:

export LD_LIBRARY_PATH=./lib

此时,再次运行可执行文件,然后又出错,提示如下:
    This application failed to start because it could not find or load the Qt platform plugin "xcb".
Reinstalling the application may fix this problem.
Aborted

这个错误,我在网上搜索了下,这个错误的原因是qt5的新特性导致的,最终的解决办法在工程目录创建platforms目录,然后把安装qt5的目录的lib所在目录的同一级目录的plugins/platforms里面的libqxcb.so拷贝到刚才新建的platforms目录,重新运行可执行文件,可以正常运行,此时我把LD_LIBRARY_PATH环境变量置为空也正常了。

http://blog.csdn.net/u013281495/article/details/50540798

Linux下同时运行不同版本的qt程序的更多相关文章

  1. 【最详细最完整】在Linux 下如何打包免安装的QT程序?

    在Linux 下如何打包免安装的QT程序? 版权声明:嵌入式linux相关的文章是我的学习笔记,基于Exynos 4412开发板,一部分内容是总结,一部分是查资料所得,大家可以自由转载,但请注明出处! ...

  2. linux下使用命令模式去编译Qt程序

    1.打开终端输入,qmake -v ,如果提示版本信息正,就可以编译程序了. 2.当前目录切换到程序源代码目录,cd /home/likewei/untitled2 3.生成untitled2.pro ...

  3. Linux 下编译、安装、配置 QT

    转自Linux 下编译.安装.配置 QT 注意:编译安装耗时费力,且很容易出错,要不断调整编译参数,不推荐使用,否则这将会是一个纠结痛苦的过程. 打算做嵌入式图像处理,计划方案嵌入式Linux+Ope ...

  4. linux下编译运行TIGL Viewer步骤

    linux下编译运行TIGL Viewer步骤(仅为了正确编译安装的话直接跳到步骤3) 1. linux发行版选择:由于linux发行版众多,不同版本包含的库版本可能存在差别,因此需要选择正确的版本. ...

  5. Atitit linux获取项目运行环境版本

    Atitit linux获取项目运行环境版本 1.1. Nginx版本1 1.2. Php版本1 1.3. Mysql版本2 1.4. Redis版本2 1.1. Nginx版本 [root@iZ25 ...

  6. linux下编译运行驱动

    linux下编译运行驱动 嵌入式linux下设备驱动的运行和linux x86 pc下运行设备驱动是类似的,由于手头没有嵌入式linux设备,先在vmware上的linux上学习驱动开发. 按照如下方 ...

  7. linux 下 tomcat 运行报错 Broken pipe

    linux 下 tomcat 运行报错 Broken pipe 感谢:http://hi.baidu.com/liupenglover/blog/item/4048c23ff19f1cd67d1e71 ...

  8. Linux下启动Oracle服务和监听程序步骤

    Linux下启动Oracle服务和监听程序启动和关闭步骤整理如下: 1.安装oracle: 2.创建oracle系统用户: 3./home/oracle下面的.bash_profile添加几个环境变量 ...

  9. linux下C调用lua的第一个程序

    linux下C调用lua的第一个程序 linux的环境是Fedora 18,运行在VM workstation中,以开发模式安装,自带了lua 5.1.4,可以在命令行上直接用lua命令进入到lua环 ...

随机推荐

  1. 比较优势 - MBA智库百科

    比较优势 - MBA智库百科 比较优势 出自 MBA智库百科(http://wiki.mbalib.com/)   这是一个消除歧义页--使用相同或相近标题,而主题不同的条目列表.如果您是通过某个内部 ...

  2. PS图片

    第二次练习PS,不知道找什么图片,就这么做着吧.然后自己学习了下动画制作,但是中间有些问题,需要再研究研究. 像 CS6中新建蒙版文档,画出的图形单位是厘米,怎么改为像素?(答案看后续博客....)

  3. 获取sdcard和内存的存储空间

    package com.example.sdcardspace; import java.io.File; import android.os.Bundle; import android.os.En ...

  4. [转]Centos 6.5 优化 一些基础优化和安全设置

    关于CentOS服务器的优化下文作为参考. 本文 centos 6.5 优化 的项有18处: 1.centos6.5最小化安装后启动网卡2.ifconfig查询IP进行SSH链接3.更新系统源并且升级 ...

  5. Qt核心剖析: moc

    前面我们说过,Qt 不是使用的“标准的” C++ 语言,而是对其进行了一定程度的“扩展”.这里我们从Qt新增加的关键字就可以看出来:signals.slots 或者 emit.所以有人会觉得 Qt 的 ...

  6. Android NumberPicker和DatePicker分割线颜色设置

    NumberPicker /** * * 设置选择器的分割线颜色 * * @param numberPicker */ private void setDatePickerDividerColor(N ...

  7. intent.getAction()

    这个是发送端注册上的IntentFilter filter = new IntentFilter( Intent.ACTION_MEDIA_SCANNER_STARTED); filter.addAc ...

  8. java设计模式之——适配器模式

    适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 适配器模式的用途 用电器做例子,笔记本电脑的插头一般都是三相的,即除了阳极.阴极 ...

  9. ajaxSubmit提交文件表单不执行success

    先描述一下我遇到的问题,系统里所有的表单都用ajaxSubmit来提交,成功回调success函数,普通表单都是没有问题的,但是有文件上传的表单就不行了,不会回调success,经验证会回调compl ...

  10. SQL之单行函数

    单行函数语法: function name(column|expression,[arg1,arg2,...]) 参数说明: function name:函数名称 column:数据库列名 expre ...