Linux下同时运行不同版本的qt程序
因项目需要,可能有不同版本的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程序的更多相关文章
- 【最详细最完整】在Linux 下如何打包免安装的QT程序?
在Linux 下如何打包免安装的QT程序? 版权声明:嵌入式linux相关的文章是我的学习笔记,基于Exynos 4412开发板,一部分内容是总结,一部分是查资料所得,大家可以自由转载,但请注明出处! ...
- linux下使用命令模式去编译Qt程序
1.打开终端输入,qmake -v ,如果提示版本信息正,就可以编译程序了. 2.当前目录切换到程序源代码目录,cd /home/likewei/untitled2 3.生成untitled2.pro ...
- Linux 下编译、安装、配置 QT
转自Linux 下编译.安装.配置 QT 注意:编译安装耗时费力,且很容易出错,要不断调整编译参数,不推荐使用,否则这将会是一个纠结痛苦的过程. 打算做嵌入式图像处理,计划方案嵌入式Linux+Ope ...
- linux下编译运行TIGL Viewer步骤
linux下编译运行TIGL Viewer步骤(仅为了正确编译安装的话直接跳到步骤3) 1. linux发行版选择:由于linux发行版众多,不同版本包含的库版本可能存在差别,因此需要选择正确的版本. ...
- 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 ...
- linux下编译运行驱动
linux下编译运行驱动 嵌入式linux下设备驱动的运行和linux x86 pc下运行设备驱动是类似的,由于手头没有嵌入式linux设备,先在vmware上的linux上学习驱动开发. 按照如下方 ...
- linux 下 tomcat 运行报错 Broken pipe
linux 下 tomcat 运行报错 Broken pipe 感谢:http://hi.baidu.com/liupenglover/blog/item/4048c23ff19f1cd67d1e71 ...
- Linux下启动Oracle服务和监听程序步骤
Linux下启动Oracle服务和监听程序启动和关闭步骤整理如下: 1.安装oracle: 2.创建oracle系统用户: 3./home/oracle下面的.bash_profile添加几个环境变量 ...
- linux下C调用lua的第一个程序
linux下C调用lua的第一个程序 linux的环境是Fedora 18,运行在VM workstation中,以开发模式安装,自带了lua 5.1.4,可以在命令行上直接用lua命令进入到lua环 ...
随机推荐
- 敬请贤者:WEB、IOS开发(2年以上经验,大专);CTO、产品经理,运营专员 电商服装鞋饰买手(2年以上经验,服装或鞋类);体验店店长 (2年以上经验,服装或鞋类) 工作地点:丰台南苑路;有意者小窗QQ2211788980 - V2EX
敬请贤者:WEB.IOS开发(2年以上经验,大专):CTO.产品经理,运营专员 电商服装鞋饰买手(2年以上经验,服装或鞋类):体验店店长 (2年以上经验,服装或鞋类) 工作地点:丰台南苑路:有意者小窗 ...
- win32多线程程序设计笔记(第五章)
前面章节介绍了线程创建等过程,现在的问题是:如何在某个线程内终止另外一个正在运行的线程? windows核心编程中提到终止运行线程的方法: 1)线程函数自己返回: 2)线程通过调用ExitThread ...
- iOS 打印日志的保存 (一)
当我们真机调试app的时候,作为开发人员的我们可以很方便的通过Xcode的debug area查看相关的打印信息.而测试人员在对app进行测试的时候,一旦出现了crash,这时我们就需要把相关的打印信 ...
- C++将文件内容一次性读入内存
结合字符串流,将文件中的内容一次性读入内存,代码如下: #include <string> using std::ostringstream; using std::ifstream; u ...
- AsyncTask简单入门
关系: java.lang.Object ↳ android.os.AsyncTask<Params, Progress, Result> 概述: AsyncTask是Andr ...
- 06-IOSCore - KVC、CoreData
一. KVC 1. KVC 使用前:黯淡无光 if ([keyPath isEqualToString:@"name"]) { self.labelName.text = self ...
- PHP - 自定义函数
第7章 自定义函数 学习要点: 1.标准函数 2.自定义函数 3.文件包含 4.魔法常量 一般来讲,冗余的代码都是不好的.一而再,再而三地重写代码不仅浪费时间,从布局结构角度看也显得粗制滥造.与所有优 ...
- Win32 进程间通信的分析与比较(13种方法)
1 进程与进程通信 进程是装入内存并准备执行的程序,每个进程都有私有的虚拟地址空间,由代码.数据以及它可利用的系统资源(如文件.管道等)组成.多进程/多线 程是Windows操作系统的一个基本特征.M ...
- 多文件上传组件FineUploader使用心得
原文 多文件上传组件FineUploader使用心得 做Web开发的童鞋都知道,需要经常从客户端上传文件到服务端,当然,你可以使用<input type="file"/> ...
- js 常用方法记事本
1.获取被选中行的名称<tab选项卡中为iframe> /* S 获取首页被选中的选项卡名称 */ var currTab = $("#layout_center_tabs&qu ...