开发板:天嵌 TQ_BASIC_V1
cpu:imx6q
交叉编译环境: ubuntu14-lts x64
目标机系统: linux kernel 4.1.15 (yocto 下载下来的)
目标:将QT5.9.1 移植进 arm linux 无桌面系统下运行。
交叉编译工具:arm-poky-linux-gnueabi-
以下是我cross toolchain路径
CROSS_COMPILE=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-
-sysroot /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa9hf-neon-poky-linux-gnueabi
前提条件是已经移植好tslib,才能继续往下进行。
其他版本的QT移植的时候都会有各种问题,换了很多版本才找到工具链能完成编译的QT5.9.1版本。
执行交叉工具链的环境变量
. /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa9hf-neon-poky-linux-gnueabi
查看工具链是否存在
arm-poky-linux-gnueabi-gcc -v
测试工具链是否正常运行
arm-poky-linux-gnueabi-gcc --sysroot=$SDKTARGETSYSROOT -mfloat-abi=hard test.c -o test
qt5.9.1 下载路径 https://download.qt.io/archive/qt/5.9/5.9.1/single/ qt-everywhere-opensource-src-5.9.1.tar.gz
解压 tar -xvJf qt-everywhere-opensource-src-5.9.1.tar.xz
进入解压路径 cd qt-everywhere-opensource-src-5.9.1
拷贝板子配置文件
cp -rf qtbase/mkspecs/linux-gnueabi-arm-g++ qtbase/mkspecs/arm-poky-linux-gnueabi-g++
vim qtbase/mkspecs/arm-poky-linux-gnueabi-g++/qmake.conf
做如下修改
#
# qmake configuration for building with arm-linux-gnueabi-g++
#
MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
IMX6_CFLAGS = -march=armv7-a -mfpu=neon -DLINUX=1 -DEGL_API_FB=1
IMX6_CFLAGS_RELEASE = -O2 $$IMX6_CFLAGS
QMAKE_CFLAGS_RELEASE += $$IMX6_CFLAGS_RELEASE
QMAKE_CXXFLAGS_RELEASE += $$IMX6_CFLAGS_RELEASE
QMAKE_CFLAGS_DEBUG += $$IMX6_CFLAGS
QMAKE_CXXFLAGS_DEBUG += $$IMX6_CFLAGS
CPPFLAGS = -DNDEBUG -g2 -O3
CFLAGS = -ffunction-sections -fdata-sections
CXXFLAGS = -ffunction-sections -fdata-sections
LDFLAGS = -gc-sections
QMAKE_INCDIR = /home/fangxin/rootfs/usr/include
QMAKE_LIBDIR = /home/fangxin/rootfs/lib
EGLFS_DEVICE_INTEGRATION = eglfs_viv
QT_QPA_DEFAULT_PLATFORM = linuxfb
#QMAKE_CFLAGS += -O2 -march=armv7-a -mtune=cortex-a9 -mfloat-abi=hard --sysroot=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa9hf-neon-poky-linux-gnueabi
#QMAKE_CXXFLAGS += -O2 -march=armv7-a -mtune=cortex-a9 -mfloat-abi=hard --sysroot=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa9hf-neon-poky-linux-gnueabi
PKG_CONFIG_SYSROOT_DIR = /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa9hf-neon-poky-linux-gnueabi
#PKG_CONFIG_LIBDIR = /home/fangxin/rootfs/usr/local/Qt5.8.0/lib:/home/fangxin/rootfs/usr/locat/tslib/include
PKG_CONFIG_LIBDIR = /home/fangxin/rootfs/usr/local/Qt5.9.1/lib
# modifications to g++.conf
QMAKE_CC = arm-poky-linux-gnueabi-gcc -O2 -march=armv7-a -mtune=cortex-a9 -mfloat-abi=hard --sysroot=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa9hf-neon-poky-linux-gnueabi
QMAKE_CXX = arm-poky-linux-gnueabi-g++ -O2 -march=armv7-a -mtune=cortex-a9 -mfloat-abi=hard --sysroot=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa9hf-neon-poky-linux-gnueabi
QMAKE_LINK = arm-poky-linux-gnueabi-g++ -O2 -march=armv7-a -mtune=cortex-a9 -mfloat-abi=hard --sysroot=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa9hf-neon-poky-linux-gnueabi
QMAKE_LINK_SHLIB = arm-poky-linux-gnueabi-g++ -O2 -march=armv7-a -mtune=cortex-a9 -mfloat-abi=hard --sysroot=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa9hf-neon-poky-linux-gnueabi
# modifications to linux.conf
QMAKE_AR = arm-poky-linux-gnueabi-ar cqs
QMAKE_OBJCOPY = arm-poky-linux-gnueabi-objcopy
QMAKE_NM = arm-poky-linux-gnueabi-nm -P
QMAKE_STRIP = arm-poky-linux-gnueabi-strip
load(qt_config)
保存文件qmake.conf
-mfloat-abi=hard --sysroot=/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa9hf-neon-poky-linux-gnueabi 这两个参数非常重要,
一定要加在工具链后面,否则会报错
can't find stdio.h
read-ld: cant find crut1.0 等等各种错误。切记切记。
第一步 执行
./configure -v -prefix /home/fangxin/rootfs/usr/local/Qt5.7.0 -sysroot /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa9hf-neon-poky-linux-gn ueabi -xplatform arm-poky-linux-gnueabi-g++ -no-opengl -nomake examples -nomake tools -no-separate-debug-info -qreal float -qt-zlib -tslib -I/home/fangxin/rootfs/usr/local/tslib/include -L/home/fangxin/rootfs/usr/local/tslib/lib
注意:build target -> arm 编译的目标板是arm 才行哈。
-no-opengl 如果不加这个会报 opengl function test failed! 错误。
第二步 make 这个过程比较长,全部库都编译的话大概三个小时。也可以先把主目录下一些文件夹删掉裁剪一些不需要的库,减少编译时间。
第三部 sudo make install . 由于./configure -prefix /home/fangxin/rootfs/usr/local/Qt5.9.1 指定安装目录,但是最终会安装在/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa9hf-neon-poky-linux-gnueabi/home/fangxin/rootfs/usr/local/Qt5.9.1/ 这个目录下。 所以需要将起拷贝到开发板 /home/fangxin/rootfs/usr/local/Qt5.9.1 下。
四、交叉编译QT应用程序
给出hello-QT应用程序测试例程,主要是三个文件main.cpp、mainwindow.cpp、mainwindow.h,使用命令行qmake交叉编译程序:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
QSpinBox *spinBox = new QSpinBox;
QSlider *slider = new QSlider(Qt::Horizontal);
spinBox->setRange(0, 130);
slider->setRange(0, 130);
QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)));
QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int)));
spinBox -> setValue(35);
QPushButton *button = new QPushButton("Quit");
QObject::connect(button, SIGNAL(clicked()), this, SLOT(exitBtn_slot()));
QHBoxLayout *layout = new QHBoxLayout();
layout->addWidget(spinBox);
layout->addWidget(slider);
layout->addWidget(button);
QHBoxLayout* layout1 = new QHBoxLayout();
QPushButton* okBtn = new QPushButton(("OK"));
this->label = new QLabel();
QSpacerItem* horizontalSpacerItem = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
layout1->addWidget(label);
layout1->addSpacerItem(horizontalSpacerItem);
layout1->addWidget(okBtn);
QObject::connect(okBtn, SIGNAL(clicked(bool)), this, SLOT(okBtn_slot()));
QVBoxLayout* mainLayout = new QVBoxLayout();
mainLayout->addLayout(layout);
mainLayout->addLayout(layout1);
QWidget *window = new QWidget();
window->setLayout(mainLayout);
window->setFixedSize(320, 200);
this->setCentralWidget(window);
this->setWindowTitle("Test");
}
MainWindow::~MainWindow()
{
this->close();
}
void MainWindow::okBtn_slot()
{
cnt++;
if(cnt%2)
{
label->setText(("Are You Ok !"));
}else {
cnt=0;
label->setText((" "));
}
}
void MainWindow::exitBtn_slot()
{
this->close();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QSlider>
#include <QSpinBox>
#include <QPushButton>
#include <QSpacerItem>
#include <QLabel>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void okBtn_slot();
void exitBtn_slot();
private:
// Ui::MainWindow *ui;
unsigned char cnt = 0;
QLabel* label = new QLabel();
};
#endif // MAINWINDOW_H
进入到hello文件夹下,执行命令
qmake -project
qmake
make
此处注意qmake的路径在 安装路径/qt5.9.1/bin/qmake 。
make报错后在工程文件中hello.pro文件中添加
QT += core widgets
编译成功,将可执行文件hello拷贝到ARM板上,执行,结果如下
懒得上传运行图片了,参考下面链接。
https://blog.csdn.net/kuangzuxiaoN/article/details/78971030
QT汉化
先上传自己 /etc/profile 里 tslib 和 qt 的配置
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
#set hostname
HOSTNAME='/bin/hostname'
export HOSTNAME
#set PS1
PS1='[\u@\h\W]\$'
export PS1
# tslib
export TSLIB_ROOT=/usr/local/tslib
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf
export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
#export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TSLIB_ROOT/lib
# qt5.8.0
export QTDIR=/usr/local/Qt5.9.1
export PATH=$QTDIR/bin:$PATH
export QT_QPA_GENERIC_PLUGINS=tslib
export QT_QPA_PLATFORM_PLUGIN_PATH=$QTDIR/plugins
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0:size=1024x600:mmSize=1024x600:offset=0x0:tty=/dev/tty1
export QT_QPA_FB_TSLIB=1
#export QT_QPA_FB_HIDECURSOR=/dev/input/event1
#export LD_PRELOAD=$QTEDIR/lib/preloadable_libiconv.so
export QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event1
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$QTDIR/lib:/lib:/usr/lib:/usr/local/lib:
#$TSLIB_ROOT/lib
echo "execute /etc/profile"
chmod +x /etc/rc.d/rc.local
source /etc/rc.d/rc.local
自己去网上下载个字库 放进 export QT_QPA_FONTDIR=$QTDIR/lib/fonts 路径下就可以。
我的字库是 wqy-microhei.ttc,放进去以后应该起码能显示英文的。
显示中文的话需要utf8编码格式如下。
uart_dbg_bt = new QPushButton(QObject::trUtf8("串口调试"));
转换格式后就能显示中文。