因项目需要,可能有不同版本的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. oschina娱乐游戏

    休闲游戏 123网络游戏 88单机游戏 201游戏模拟器/工具/引擎

  2. 基于visual Studio2013解决算法导论之029二叉搜索树

     题目 二叉搜索树 解决代码及点评 #include <stdio.h> #include <malloc.h> #include <stdlib.h> ty ...

  3. xcode4.5.1、iphone5、ios6 使用记录

    链接地址:http://blog.sina.com.cn/s/blog_6123f9650101dmo7.html 1.修改工程名:直接选中工程名点一下,就像修改名称夹名称一样简单了.   2.导入旧 ...

  4. 说说关于php内置函数curl_init()

    昨天在我本地的项目,调试时碰到无法识别curl_init()方法,网上查了查才知道是我本地的php.ini文件里没加载上,完了把extension=php_curl.dll前面的;去掉后就好了,注意一 ...

  5. Creating Spatial Indexes(mysql 创建空间索引 The used table type doesn't support SPATIAL indexes)

    For MyISAM tables, MySQL can create spatial indexes using syntax similar to that for creating regula ...

  6. I/O操作技术

     对I/O操作有三种可能的技术:可编程I/O.中断驱动I/O.直接内存存取(DMA) 可编程I/O 当处理器正在运行程序并遇到一个与I/O相关的指令时,它通过给对应的I/O模块发命令来运行这个指令 ...

  7. android保存文件到SD卡中

    想把文件保存到SD卡中,一定要知道SD卡的路径,有人说可以用File explore来查看,这种方法不太好,因为随着android版本的升级,SD卡的路径可能会发生改变.在1.6的时候SD的路径是/s ...

  8. Troubleshooting:lvm调整分区时“Error parsing metadata for VG fedora”的解决

    磁盘满了,由于使用的是lvm,想要扩容时发现无论lvs还是lvdisplay这类命令都会报同样的错: [root@localhost qwang]# lvs Parse error at (line ...

  9. wxWidgets帮助文档(1)

    IMPLEMENT_APP IMPLEMENT_APP(className) 这是在应用程序中使用类的实现文件的应用程序类wxWidgets动态建筑.你用这个代替Old form: MyApp myA ...

  10. SVN 1.8.x 服务器安装(转)

    目录[-] 一. SVN 服务器下载.安装 1. 关于 Subversion 1.8.11 2. 兼容性问题 3. 安装包下载 3.1 VisualSVN 3.2 Win32Svn 3.3 SlikS ...