linux 下用arm体系QT编译问题(目前我系统里有X86 和 arm体系(老师编好的)的QT各一个)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux 下用arm体系QT编译问题(目前我系统里有X86 和 arm体系(老师编好的)的QT各一个)相关的知识,希望对你有一定的参考价值。
我想在linux里用arm版的QT 编译程序hello.cpp ,环境变量PATH 和 lib 路径均已添加好完毕
[root@localhost test2]# ls
hello.cpp
[root@localhost test2]# which qmake
/media/sdb/qt_arm_4.6.2/bin/qmake
[root@localhost test2]# qmake -project
QFileInfo::absolutePath: Constructed with empty filename
[root@localhost test2]# qmake
[root@localhost test2]# make
arm-linux-g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/media/sdb/qt_arm_4.6.2/mkspecs/qws/linux-arm-g++ -I. -I/media/sdb/qt_arm_4.6.2/include/QtCore -I/media/sdb/qt_arm_4.6.2/include/QtNetwork -I/media/sdb/qt_arm_4.6.2/include/QtGui -I/media/sdb/qt_arm_4.6.2/include -I. -I. -o hello.o hello.cpp
arm-linux-g++ -Wl,-O1 -Wl,-rpath,/media/sdb/qt_arm_4.6.2/lib -o test2 hello.o -L/media/sdb/qt_arm_4.6.2/lib -lQtGui -L/usr/local/arm/tslib/build/lib/ -L/media/sdb/qt_arm_4.6.2/lib -lQtNetwork -lQtCore -lpthread
/home/usr/local/arm/3.4.1/bin/../lib/gcc/arm-linux/3.4.1/../../../../arm-linux/bin/ld: warning: libts-0.0.so.0, needed by /media/sdb/qt_arm_4.6.2/lib/libQtGui.so, not found (try using -rpath or -rpath-link)
/home/usr/local/arm/3.4.1/bin/../lib/gcc/arm-linux/3.4.1/../../../../arm-linux/bin/ld: warning: libz.so.1, needed by /media/sdb/qt_arm_4.6.2/lib/libQtGui.so, not found (try using -rpath or -rpath-link)
/media/sdb/qt_arm_4.6.2/lib/libQtCore.so: undefined reference to `uncompress'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `deflate'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `inflate'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `ts_close'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `ts_config'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `inflateInit_'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `deflateInit_'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `ts_read'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `ts_read_raw'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `ts_open'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `crc32'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `deflateInit2_'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `inflateReset'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `deflateReset'
/media/sdb/qt_arm_4.6.2/lib/libQtCore.so: undefined reference to `compress2'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `ts_fd'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `compress'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `inflateEnd'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `inflateInit2_'
/media/sdb/qt_arm_4.6.2/lib/libQtGui.so: undefined reference to `deflateEnd'
collect2: ld returned 1 exit status
make: *** [test2] Error 1
[root@localhost test2]# 如能解答感激涕0
仅作参考 参考技术A 手动在makefile文件里面加入“ -L/usr/lib”试试看 参考技术B 函数库放错地方或者还是编译的设置有问题。 参考技术C 没有用 qt creator?
hello源代码?
环境变量设置?
库的使用?追问
我问我?
追答只是给你提示,问题要自己找。
你就给了一个编译过程,没有源程序,没有其他说明,只看问题是说差libQtGui.so 库,你到安装路径下去看看有没有,是不是qt安装的时候有问题?
arm-linux 程序开发入门(QT窗口应用程序编码交叉编译调试)(三机器和双机器搭建方法)(笔记)
文章目录
前言
本文记录了自己从一个完全不懂Linux的人如何一步步学会Linux程序开发的过程。当然也希望本文能够达到它的目的,让那些和我一样没有任何基础的人也能快速入门Linux程序开发。
一、Arm-Linux程序开发平台简要介绍
Arm-Linux程序的开发并不像我们以前接触的Windows程序开发那样,关于平台的搭建就繁琐很多,所以在正式进入程序开发之前先对这种开发模式进行简要介绍,让一个即使没有任何Linux开发经验的程序员也能够看懂后面的内容。
1.1程序开发所需系统及开发语言
开发arm-linux程序至少需要三种系统:
-
Windows系统。
主要用来文件传送和一些简单的文本文件编辑。这个系统其实并非必需,只是因为目前PC机上最流行的系统仍然是Windows系统,我们的很多关于PC的文件和数据的操作习惯都是在Windows系统上养成的,已经对其形成了严重的依赖,所以Windows系统扮演着的“辅助开发系统”的角色。 -
PC-Linux系统。
在此系统上安装arm-Linux交叉编译器后,就可以对代码文本文件进行编译,生成可在arm-Linux系统中运行可执行程序。此系统被称为“Linux宿主机”,我们对Linux程序的开发工作(包括代码编写、调试和编译生成可执行文件)基本上就是在此系统上进行的。 -
Arm-Linux系统。
Arm-Linux程序运行的平台。此系统的硬件载体是一块小型的嵌入式arm板,我们在Linux宿主机上开发好程序并编译生成arm-linux可执行程序后,将可执行程序文件传送到嵌入式arm板中,然后就可以在arm板上直接运行此程序了。
三种系统的职能和联系如下图:
关于每个系统的职能及操作还有文件如何传送交流都在后面详细介绍。
关于开发语言,因为目前购买的Arm-Linux嵌入式板提供的编译库都是C/C++的,所以一般选择C/C++进行程序设计。
1.2系统平台搭建方式
关于“三系统”的搭建方式,有两种方法:三台分立的单系统机器组合或者一台双系统PC机和一台单系统Arm板机器。但是不管采用哪种组合方式,各种系统的职能都是一样的,而且都是通过FTP、Telnet或者SSH等网络协议进行文件传输交流。
-
“三机器”组合模式。将三个系统分别安装在三台机器上并将三台机器组建局域网。
-
“两机器”组合模式。在PC机上利用虚拟工作站可以同时运行两个系统,虚拟机上的Linux系统基本可以完成所有的实体PC-Linux机器的所有任务,当然也能够组建局域网。
“三机器”组合模式图
“两机器”组合模式图
如果开发人员对机器性能要求比较高,那么建议采用“三机器”组合模式。因为“两机器”组合模式要求一台机器运行双系统,每个系统都需要分配一定的硬件资源,可能会对每个系统运行的流畅程序都造成影响。
如果开发人员只进行一些简单的程序开发,则建议采用“两机器”组合模式。这样可以节省硬件设备的投资,而且开发环境的搭建、开发的流程等等都会简单一些。而且下面的内容都是基于这种“两机器”组合的开发模式。
二、Linux开发平台搭建(略)
2.1安装虚拟工作站
目前比较流行的虚拟工作站比较多,推荐使用VM-ware WorkStation。建立虚拟工作站的目的就是为了使一台机器同时运行多个不同类型的系统,方便开发人员进行跨平台开发应用程序。
(关于VMware,可以到网上搜索到详细介绍和使用方法,在此不再赘述)
2.2 安装Linux虚拟机
略
略略略
三、Fedora-linux系统(略)
四、使用Eclipse CDT开发Linux程序(略)
五、使用Eclipse开发Arm-linux程序
Arm-Linux机器采用的是飞凌嵌入式技术公司的FL2440开发板。在飞凌公司购买开发板的时候,会随开发板一起赠送的相关入门教程《飞凌开发板配套教程》并附有一张光盘,里面有各种写FL2440相关的开发资源。
在正式进入程序开发之前,先对FL2440开发板及arm-linux系统进行熟悉。
Fl2440开发板:熟悉Bootloader的使用方法、学会烧写内核、烧写文件系统等等。
Arm-linux系统:熟悉利用一些文件系统和网络设置相关的命令。如果你对Linux命令已经有了一定了解,那么arm-linux上的命令也基本一样。
(详细操作过程请参考《飞凌开发板配套教程》一书)
5.2开发控制台程序
主要开发流程图如下:
在早期的开发环境方式中,是先用文本编辑器编写c或者cpp文件,然后再直接在Linux机器上通过交叉编译命令,编译代码文本文件并生成可执行程序,然后将可执行程序传送到arm-linux板上,然后就可以在arm-linux机器上运行程序了。
现在的开发模式和早期的开发模式一样,只是在编写代码的工具上进行了改进。早期编写代码的工具只要是能编辑文本的软件就可以,甚至在Linux中通过终端的vi命令就可以搞定,Linux机器的职能仅仅是编写代码和编译代码。现在则使用Eclipse CDT,可以在Linux机器上编写C/C++代码并进行调试,Linux机器基本上可以模拟arm-linux系统上除了一些硬件相关度高的应用程序(如驱动程序)之外的绝大部分其它程序的运行环境。(摄像头不可模拟吗?)
5.2.1使用Eclipse CDT编写代码
其实和用Eclipse CDT编写Linux环境下的控制台程序是完全一样。除了在一些特别的场合,比如编写驱动程序,需要注意差别外,其余的功能的实现方法基本上一样。
这方面属于程序设计的基本功,需要长期学习和积累,所以在此不再多述。
5.2.2建立交叉编译环境
虽然生成程序的源码是一样的,但是在Linux机器上编译生成的可执行文件是不能在arm-linux系统上运行的,需要用arm-linux专用的编译器进行编译后,才能生成可在arm-linux系统上运行的可执行文件,当然此时应用程序又显然不能在Linux系统上运行了。
将交叉编译工具cross-2.95.3.tar.bz2(可以到网上下载,也可以到开发板附带的光盘资源中找到)通过共享目录传送到Linux系统中,然后在Linux系统终端中先进入其文件目录,然后执行解压命令:
tar xjvf cross-2.95.3.tar.bz2
然后在/usr/local/arm文件目录下可以看到解压后的2.95.3的库了,或者如果你解压的是cross-3.4.1.tar.bz2的版本,那么将会在对应目录下生成3.4.1的目录。
然后设置环境变量。因为Linux机器上存在不止一种编译器,为了避免环境变量冲突,最好新建一个账号(用户【大概是有的编译器指令相同,需要避免环境变量冲突,所以需要新建用户?】),比如新建账号arm-linux-gcc,然后在对应的账号目录中找到.bash_profile文件,设置环境变量,编辑.bash_profile,在最后一行增加路径(vi打开文本文件,按i表示insert修改文本文件,然后Esc退出insert模式,再shift zz表示保存退出文件,详细的命令介绍可以到网上查阅相关资料):
export PATH=/usr/local/arm/2.95.3/bin:$PATH
可以通过echo $PATH来查看环境变量是否设置成功:
5.2.3编译并运行程序
在编辑好了代码文件并建立好了交叉编译环境后,就开始编译代码生成可执行程序,并移植到arm板上运行程序。
在Linux系统的终端中通过输入arm-linux-gcc/arm-linux-g++来编译C/C++文件。例如,我们对前面编写的最简单的CppHelloWorld.cpp文件进行编译:
arm-linux-g++ CppHelloWorld.cpp –o CppHello
然后在对应目录下会生成一个可在arm-linux系统上运行的应用程序CppHello。
然后通过SSH服务和FTP服务,将可执行文件从Linux文件系统网络传送到arm-linux文件系统(在此用到了两个小软件SSH Secure和LeapFTP,在后面再对软件的功能进行一下简要介绍)。
然后在Windows机器上远程登录arm-linux系统开发板,并控制程序运行
注意:需要先通过chmod +x CppHello来告诉系统此文件是可执行文件,然后再通过./CppHello来运行程序。
我们可以看到程序运行的结果:在屏幕上打印出一行字“Hello World”
5.3一些常用的软件介绍
在上面介绍的一些操作中,在进行文件传送的时候用到了一些软件,在此进行简要介绍。(经过数十年的发展,新出了一些软件,比如Xshell之类的)
三系统之间的主要网络架构如下:
注意:
1.如果arm-linux系统的ftp和telnet连接不上,一般情况下是arm-linux默认没有开启相应的服务或者默认ip和windows机器不在同一网段。可以通过串口线将arm板连接到电脑上,然后打开超级终端,输入命令vsftpd&开启ftp服务,输入命令telnetd开启telnet服务,ifconfig eth0 192.168.1.16设置IP到同一网段。
2.如果Linux系统的SSH连接不上,则一般情况下是Linux系统开启了SSH的防火墙,则只需要在Linux系统中对防火墙进行相关设置,关闭针对SSH的防火墙。【System】–【Administration】–【Firewall】,然后勾选全能SSH。
还有一些其它软件,比如小组协作时候,需要使用SVN进行代码管理;还有远程桌面VNC Viewer,可以进行远程桌面控制(但是效果不太好,桌面显示的延时好像比较严重)等等。
5.4开发arm-linux窗口程序
5.4.1建立Qt交叉编译环境
在Linux系统中新建目录/root/yizhi,然后将已经编译好的arm-QT库复制到此目录下面。
然后将上面那六个tar.gz压缩文件解压到/root/yizhi目录。
在进行arm-linux下的Qt编译的时候,也涉及到环境变量设置问题,所以我们也最好再新建一个账户,专门用于编译arm-Qt程序。
例如,在Linux系统终端中添加用户zsm,然后进入到/home/zsm中,对.bash_profile进行修改,设置环境变量:
(为什么要管环境变量,这关环境变量什么事?)
在命令终端中ls –a 显示隐藏的所有文件 找到.bash_profile,输入:
gedit .bash_profile &
用geidt打开此文件后,在最后面添加下面的环境变量设置:
export PATH=/root/yizhi/qtopia-free-2.2.0/qtopia/bin:/root/yizhi/qtopia-free-2.2.0/tmake/bin:/root/yizhi/qtopia-free-2.2.0/qt2/bin:/usr/local/arm/2.95.3/bin:$PATH
export QTDIR=/root/yizhi/qtopia-free-2.2.0/qt2
export QTEDIR=/root/yizhi/qtopia-free-2.2.0/qtopia/
export LD_LIBRARY_PATH=$QTDIR/lib:$QPEDIR/lib:$LD_LIBRARY_PATH
export CC=/usr/local/arm/2.95.3/bin/arm-linux-gcc
export TMAKEDIR=/root/yizhi/qtopia-free-2.2.0/tmake
export TMAKEPATH=$TMAKEDIR/lib/qws/linux-arm-g++
设置好后最好重新登录此账号,然后在终端中输入echo $PATH来检验环境变量是否设置成功:
如果出现上面的输出,则表示arm-linux平台下的Qt交叉编译环境的环境变量已经设置成功。接下来就可以进行Qt程序开发了。
5.4.2编译生成可执行窗体程序
在3.2节中已经写好了一个单文件的项目QtHello,并在项目的src目录下生成了一个QtHello.cpp文件,然后我们要做的就是利用arm-linux下的Qt编译器对其进行编译。
编译Qt窗体项目比编译普通控制台项目要稍微麻烦一点,需要自己写makefile来建立编译规则,编译如上的QtHello.cpp的makefile有如下模板:
#############################################################################
# Makefile for building hello
# Generated by tmake at 20:58, 2011/04/14
# Project: hello
# Template: app
#############################################################################
####### Compiler, tools and options
CC = arm-linux-gcc
CXX = arm-linux-g++
CFLAGS = -pipe -Wall -W -O2 -DNO_DEBUG
CXXFLAGS= -pipe -DQWS -fno-exceptions -fno-rtti -Wall -W -O2 -DNO_DEBUG
INCPATH = -I. -I$(QTDIR)/include
LINK = arm-linux-gcc
LFLAGS =
LIBS = $(SUBLIBS) -L$(QTDIR)/lib -lm -lqte
MOC = $(QTDIR)/bin/moc
UIC = $(QTDIR)/bin/uic
TAR = tar -cf
GZIP = gzip -9f
####### Files
TARGET = QtHello
HEADERS = $(TARGET).h
SOURCES = $(TARGET).cpp
OBJECTS = $(TARGET).o
DIST =
INTERFACE_DECL_PATH = .
####### Implicit rules
.SUFFIXES: .cpp .cxx .cc .C .c
.cpp.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
.cxx.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
.cc.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
.C.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
.c.o:
$(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
####### Build rules
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS)
dist:
$(TAR) hello.tar hello.pro $(SOURCES) $(HEADERS) $(INTERFACES) $(DIST)
$(GZIP) hello.tar
clean:
-rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) $(TARGET)
-rm -f *~ core
####### Sub-libraries
###### Combined headers
####### Compile
$(TARGET).o: $(TARGET).cpp
用zsm账号登录(因为关于arm-Qt库的编译环境变量是在此账号中设置的),然后执行如下步骤:
1.将makefile模板文件放置到src目录下面
2.用eclipse或者其它文本编辑器,修改makefile里面的TARGET一项为当前项目名称
3.打开Teminal控制终端,进入到src目录,输入make
4.然后会在src目录下面生成一个指定名称相应的QtHello文件,这个就是arm目标板上的运行程序了。
5.将QtHello文件传送到arm板并运行程序(详细操作方法在4.2.3节中有介绍)。
在Windows机器上远程登录arm板,控制程序运行,然后可以看到arm板上运行的结果了。
六、高级Linux程序设计
前面所介绍的不管是控制台还是窗体程序,都属于单文件项目的范围。而当程序的功能比较复杂时,则往往需要很多模块和文件,这样在向arm-linux上移植程序时会更加繁琐一些,需要开发人员自己写makefile,建立多文件的编译规则。
因为我对此没有进入深入一点的研究,所以只能提供下大致思路和在开发程序时遇到的一些常见问题及解决方案。如果今后有机会有时间的话,则会对makefile进行深入一点的研究,最好是能以Eclipse自己生成的makefile模板为基础进行简单的修改,然后就可以编译生成arm板上的可执行程序。
6.1多文件控制台项目
多文件的控制台程序的makefile可能会容易一些,自己也没有研究过,以前在使用Magic C++编写C++控制台程序的时候,只需要对Magic C++生成的makefile模块中的编译器进行修改就可以轻松为多文件生成基于arm-linux平台上的控制台程序。
(关于如何对Eclipse的makefile模板进行修改,目前还没有研究过,今后有时间研究的话,再补充上吧。)
6.2 多文件Qt项目
目前只对简单的多文件项目进行了尝试:一个main函数文件,一个窗体头文件,一个窗体实现文件。
6.2.1 使用Qt Designer设置界面
在Linux系统中打开Qt Designer,然后进行可视化窗口设计。然后点击保存为mydialog.ui文件。
打开mydialog.ui文件,发现其实只是一个xml文件:
显然这个文件是不能直接被C++项目引用的,需要使用Qt Designer的编译器进行编译,生成和界面对应的h和cpp文件。
在Terminal终端里面运行以下命令:
uic xxx.ui -o xxx.h 生成.h文件
uic xxx.ui -i xxx.h -o xxx.cpp 生成.cpp文件
然后生成的mydialog.h和mydialog.cpp文件就是和mydialog.ui相对应的程序代码文件了。可以在Eclipse项目中直接对此文件进行引用,就可以显示对应的窗体了。
6.2.2 多文件Qt开发时的一些经典错误
- 经典错误一:
“undefined reference to ……”
这是在引用Qt的库时,产生了某些歧义,需要进行一些预先处理,生成和界面文件相对应的moc文件,关于问题的详细介绍可以参考下面的帖子:
http://hi.baidu.com/asky007/blog/item/7aad95ccbee5ba1601e928d7.html
(靠,太多年了,已经打不开了!)
解决方案:
在Linux控制终端中进入到项目代码文件目录,执行
qmake –project
qmake
make
然后此目录下会生成一系列的文件,如moc_xx.cpp,moc_xx.o,src,src_pro等等。然后再到Eclipse中编译此项目,则错误消失。
- 经典错误二:
在Linux机器上能运行的Qt窗口程序,在arm-linux下的Qt编译器下无法通过。
可能的问题是Qt库版本问题,或者是有些Qt运行环境在Linux机和arm-linux机上有所不同,这就需要重新寻找新的代替解决方案。正是因为这些很多不确定的因素,所以在进行arm-linux界面程序开发时,需要经常在编写一段新代码就要在arm板上进行测试,可以避免做太多无用功
。
6.3 关于makefile
关于多文件Qt项目向arm-linux系统上的移植,比较核心的技术应该就在makefile上吧,目前自己了解太少,只限于对模板的应用,所以下面的就写不下去了。
下面有一篇到网上找到的关于makefile结构分析的帖子,今后有机会再研究吧。
http://blog.csdn.net/liang13664759/archive/2007/09/04/1771246.aspx
https://blog.csdn.net/liang13664759/article/details/1771246
(WoW,2021年的帖子引用2011年的帖子,2011年的帖子引用2007年的帖子,牛掰!CSDN万古长青)
七、学习资料
关于Linux下的Qt开发,在安装了的Fedora里面有相关的本地reference和相关的源码。如:Qt Assistant
关于arm-linux下的Qt开发,安装交叉编译环境时候,也有相关文档和源码:
以上是关于linux 下用arm体系QT编译问题(目前我系统里有X86 和 arm体系(老师编好的)的QT各一个)的主要内容,如果未能解决你的问题,请参考以下文章
Linux系统上用QT编写ARM9继电器控制程序的问题。 想写个QT界面程序到arm板子上,通过界面的按钮来控制继电
配置qt交叉编译安装,总是提示arm-linux-g++:没有那个文件或目录