提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
相较于我们前几篇博文所介绍的编译运行适用于arm架构的64位Qt应用程序,在64位Ubuntu系统上编译运行适用于arm架构的32位Qt应用程序需要注意许多兼容性问题。
Qt 库通常是在目标开发板的操作系统安装时安装的。这意味着,Qt 库作为操作系统的一部分已经预先安装在arm目标开发板上,并且与操作系统的版本和架构兼容。开发应用程序时,需要了解目标平台的硬件和软件环境,并确保使用与目标平台兼容的 Qt 库版本。
事实上,开发应用程序时,建议使用与目标开发板相同的交叉编译工具链和相同版本的Qt 版本。这样可以确保生成的应用程序与目标系统的硬件及软件环境兼容并正常运行。
为了维护公司项目,需要Ubuntu64位系统下安装arm32位版本(Qt4.8.6和tslib1.4)开发环境,本文记录了这一配置过程。
我们使用的arm目标机上安装了qt4.8.6库,触摸屏tslib库为tslib1.4。交叉工具链则是gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313
。
1、安装交叉工具链
- 将过去备份的交叉工具链gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux.tar.gz,拷贝到/opt,解压:
sudo tar -zxvf gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux.tar.gz
- 将解压缩的工具链目录添加到环境变量中,例如添加以下行到 ~/.bashrc 文件最后:
vim ~/.bashrc
export PATH=$PATH:/opt/gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux/bin
- 运行 source ~/.bashrc 命令以更新环境变量。
source ~/.bashrc
- 验证一下:
arm-linux-gnueabihf-gcc -v
成功:
。。。
gcc version 4.7.3 20130226 (prerelease) (crosstool-NG linaro-1.13.1-4.7-2013.03-20130313 - Linaro GCC 2013.03)
失败:
Command 'arm-linux-gnueabihf-gcc' not found, but can be installed with:
sudo apt install gcc-arm-linux-gnueabihf
出现上面的错误可能的有两种原因
(1)由于我们的ubuntu系统为64位,而交叉工具链为32位,可以通过安装 lib32stdc++6 软件包来解决。
sudo apt-get install lib32stdc++6
(2)没有将相应的交叉编译器添加到 PATH 环境变量
通过在终端中执行 echo $PATH 命令查看当前环境变量中包含的路径,检查是否出错:
echo $PATH
修正后再次验证,成功。
2、必要依赖库安装
在 64 位 Ubuntu 系统上需要编译运行适用于 arm 架构的 32 位 Qt 应用程序,
sudo apt-get install build-essential libfontconfig1 mesa-common-dev libglu1-mesa-dev libpulse-dev libicu-dev libsqlite3-dev libssl-dev libxcb-xinerama0-dev libxkbcommon-dev libxkbcommon-x11-dev libasound2-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev
3、安装针对x86-32架构的zlib库
如果你要在64位的Ubuntu操作系统上使用32位交叉工具链,其中的 cc1 等组件在使用时需要访问到32位版本的共享库文件。因此,在这种情况下,如果使用的32位交叉工具链包中没有包含32位版本的 libz.so.1 文件,或者该文件没有被正确的安装和配置,就可能出现类似下面的错误信息:
。。。
libz.so.1: cannot open shared object file: No such file or directory
为了避免这种问题,可以在运行32位交叉工具链之前,通过以下命令安装32位版本的 libz.so.1 库文件:
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install zlib1g:i386
这些命令会安装针对ia32架构的zlib库,在 /usr/lib/i386-linux-gnu 目录下,cc1 和其他需要32位库的组件就可以正确加载和使用 libz.so.1 库文件了。
4、交叉编译、安装 tslib
- 安装工具和库
sudo apt-get install libtool automake autogen autoconf libsysfs-dev
其中包括:
libtool:libtool 是一个程序库工具,用于将多个目标文件组合成一个共享库或静态库。
automake:automake 是一个 Makefile 生成器,它可以根据 Makefile.am 文件自动生成 Makefile.in 文件。
autogen:autogen 是一个代码生成器,它可以帮助你自动化构建系统中的模板和代码生成。
autoconf:autoconf 用于为程序配置创建 configure 脚本,configure 脚本包含了许多用于验证系统和软件依赖性的测试。
libsysfs-dev:libsysfs 库是一个用户空间库,用于访问 Linux sysfs 文件系统,该库提供了一些帮助开发系统管理工具的函数和数据结构。
- 新建一个文件夹在我们的用户文件夹/home/linux/(~):
sudo mkdir qtools
- 拷贝之前备份的tslib1.4到这个文件夹,解压:
cp tslib-1.4.tar.gz ~/qtools/
tar -zxvf tslib-1.4.tar.gz
cd tslib
- 配置编译、安装参数
(1)设置ac_cv_func_malloc_0_nonnull 变量的值写入缓存文件
echo "ac_cv_func_malloc_0_nonnull=yes" > mytmp.cache
如果在执行 configure 脚本时不做 echo “ac_cv_func_malloc_0_nonnull=yes” > mytmp.cache,在某些情况下可能会出现下列错误:
configure 脚本无法检测到系统中的 malloc(0) 是否可以返回非空指针,因此默认情况下将 ac_cv_func_malloc_0_nonnull 变量的值设置为 no。在编译程序时,如果程序的源代码中用到了 malloc(0) 返回非空的特性(如在分配空数组时),编译过程可能会失败,并提示错误。
在某些编译环境中,没有将 ac_cv_func_malloc_0_nonnull 的值设置为非零的非空值,编译程序时可能也会出现类似的错误,因为编译器默认不支持 malloc(0) 返回非空。
在上述情况下,通过在命令行上指定变量(如 ac_cv_func_malloc_0_nonnull=yes ./configure)来强制启用 malloc(0) 返回非空的特性通常是不可取的,这可能会导致程序中其他部分出现问题。
因此,为了确保编译过程的正确性,最好在执行 configure 脚本之前将 ac_cv_func_malloc_0_nonnull 的值设置为非零的非空值,并把它写入到 mytmp.cache 中。这可以强制 configure 脚本使用正确的变量值,从而避免一些不必要的编译错误。
(2)运行 autogen.sh 脚本来生成 ./configure 脚本文件
./autogen.sh
(3)配置configure脚本参数
./configure --host=arm-linux-gnueabihf --cache-file=mytmp.cache --prefix=/home/linux/tslib-arm CC=arm-linux-gnueabihf-gcc
- 编译和安装
make -j8
make install
在 make 命令中,-j8 意味着指定 make 命令最多使用 8 个线程(也称作作业或 job)并行执行。这里的 -j 参数告诉 make 命令要并行处理多少个工作。8 是一个数字选项,表示你希望同时执行的并行任务数。
使用多线程能够加快编译过程,因为源代码的编译通常可以分为几个独立的任务并行执行,而且多线程能够更好地利用多核处理器的计算能力,提高 CPU 利用率。
需要注意的是,如果使用多线程编译,可能会导致一些问题,如编译顺序变化、依赖关系错误、内存不足等等。因此,在使用多线程编译时,需要根据实际情况慎重考虑并配置好编译环境,以确保编译的正确性。
- 运行 libtool --finish 命令来完成库的安装
在安装过程的提示中出现下面的警告:
libtool: warning: remember to run 'libtool --finish /home/linux/tslib-arm/lib/ts/'
这个警告的意思是在安装 tslib 库之后,需要运行 libtool --finish 命令来完成库的安装。具体来说,libtool --finish 命令会在库的安装目录下执行一些必要的操作,以确保库可以被正确地链接和使用。
因此我们执行:
libtool --finish /home/linux/tslib-arm/lib/ts/
安装的库已经位于以下目录:
如果您希望链接已安装的库目录 LIBDIR 中的库文件,您必须使用 libtool 并指定库文件的完整路径,或在链接时使用-LLIBDIR' 标志,并至少执行以下操作之一: 在执行期间将 LIBDIR 添加到
LD_LIBRARY_PATH’ 环境变量中
在链接时将 LIBDIR 添加到LD_RUN_PATH' 环境变量中 使用
-Wl,-rpath -Wl,LIBDIR’ 链接器标志
请求系统管理员将 LIBDIR 添加到 `/etc/ld.so.conf’ 文件中
5、QT4编译、安装
- 将过去备份的QT4.8.6源码拷贝到我们第4节建立的目录~/qtools/,解压:
cp qt-everywhere-opensource-src-4.8.6.tar.gz ~/qtools/
tar -zxvf qt-everywhere-opensource-src-4.8.6.tar.gz
- 进入 qt-everywhere-opensource-src-4.8.6 目录
cd qt-everywhere-opensource-src-4.8.6
cd mkspecs
cp -rf linux-arm-gnueabi-g++ linux-arm-gnueabihf-g++
cd linux-arm-gnueabihf-g++
- 编辑qmake.conf
vim qmake.conf
- 文件编辑结果如下:
#
# qmake configuration for building with arm-linux-gnueabihf-g++
#
MAKEFILE_GENERATOR = UNIX
TARGET_PLATFORM = unix
TEMPLATE = app
CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index
QT += core gui
QMAKE_INCREMENTAL_STYLE = sublib
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
# modifications to g++.conf
QMAKE_CC = arm-linux-gnueabihf-gcc
QMAKE_CXX = arm-linux-gnueabihf-g++
QMAKE_LINK = arm-linux-gnueabihf-g++
QMAKE_LINK_SHLIB = arm-linux-gnueabihf-g++
# modifications to linux.conf
QMAKE_AR = arm-linux-gnueabihf-ar cqs
QMAKE_OBJCOPY = arm-linux-gnueabihf-objcopy
QMAKE_STRIP = arm-linux-gnueabihf-strip
load(qt_config)
- 配置编译参数:
在解压源代码后,需要对编译参数进行配置,并指定目标平台、交叉编译器、库文件等信息。具体的编译参数可以参考 Qt 官方文档或手册,或通过 ./configure -h 命令进行查看。
回到 qt-everywhere-opensource-src-4.8.6 目录,执行下面指令:
./configure -embedded arm -xplatform linux-arm-gnueabihf-g++ -no-webkit -nomake examples -nomake demos -prefix /home/linux/qt4-arm -qt-mouse-tslib -I/home/linux/tslib-arm/include/ -L/home/linux/tslib-arm/lib/ -arch arm -shared -verbose
如果发生错误,可以按提示重新配置。
To reconfigure, run 'make confclean' and 'configure'.
- 编译并安装程序包
$ make
$ sudo make install
按照我个人的习惯,在前面的编译安装中,将
qt4-arm
和tslib-arm
两个文件夹放在了~/
夹下,如果登录ubuntu系统的用户不同,绝对路径是不同的。如果你希望将两个文件夹导出,给其他ubuntu系统使用,则这是一个不好的习惯。建议安装目录放在/opt
,会给未来的迁移减少很多麻烦。
6、安装和配置qtcreator
- 安装qtcreator
sudo apt-get install qtcreator
(2)配置qtcreator
- 切换到 「Comilers」,点击「Add」,进行如下图配置,点击「Apply」和「OK」保存设置:
- 打开 Qt Creator,选择「工具」-「选项」-「构建和运行」 - 「Qt Versions」,界面如图:
- 切换到「Kits」,点击「Add」,进行如下图配置,点击「Apply」和「OK」保存设置:
7、新建项目myfirst
(1) 新建项目 myfirst
(2)选择正确的Kits
(3)重新选择基类
(4)生成如下图的项目:
(5)打开myfirst.pro文件,增加一行“LIBS +=-lts”
(6)打开widget.ui,如下编辑:
(6)保存后编译通过,生成可执行文件myfirst,使用FTP客户端软件FileZilla,将myfirst下载到设备中,在目标板终端执行:
./myfirst -qws
屏幕上出现: