在Qt官网上下载Qt5.5.1源代码qt-everywhere-opensource-src-5.5.1.tar.xz
解压源代码包,并编辑qmake.conf文件。
默认ARM GCC环境已经搭建完毕,参考ARM40-A5 GCC交叉编译环境搭建;
tslib,sqlite3也都已经预编译完毕,参考移植TSLIB到ARM40-A5和移植SQLite3到ARM40-A5。
$ cd ~
$ xz -d qt-everywhere-opensource-src-5.5.1.tar.xz #解压文件
$ tar xvf qt-everywhere-opensource-src-5.5.1.tar
$ cd qt-everywhere-opensource-src-5.5.1/
$ vim ./qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf #编辑qmake.conf
qmake.conf文件内容:
#
# qmake configuration for building with arm-linux-gnueabi-g++
#
MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
QT_QPA_DEFAULT_PLATFORM = linuxfb #指定Qt显示驱动方式
QMAKE_CFLAGS_RELEASE += -O2 -march=armv7-a #指定处理器架构
QMAKE_CXXFLAGS_RELEASE += -O2 -march=armv7-a
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
QMAKE_INCDIR += /opt/tslib/include /opt/sqlite3/include #指定头文件,需预编译
QMAKE_LIBDIR += /opt/tslib/lib /opt/sqlite3/lib #指定库文件,需预编译
# modifications to g++.conf
QMAKE_CC = /opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-gcc -lts
QMAKE_CXX = /opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-g++ -lts
QMAKE_LINK = /opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-g++ -lts
QMAKE_LINK_SHLIB = /opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-g++ -lts
# modifications to linux.conf
QMAKE_AR = /opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-ar cqs
QMAKE_OBJCOPY = /opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-objcopy
QMAKE_NM = /opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-nm -P
QMAKE_STRIP = /opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-strip
load(qt_config)
~
经过试验发现Qt5在ARM40-A5(Atmel-A5D3)上RGB颜色显示异常,R与B调换了。
需要打上补丁linuxfb_swapRGB_2.patch,该补丁仅适用于Qt5.5.1和它之前的版本,不适用Qt5.6以后版本。
$ cd ~
$ cd qt-everywhere-opensource-src-5.5.1/
$ cd ./qtbase/
$ cp ~/linuxfb_swapRGB_2.patch ./ #复制补丁文件到当前目录下
$ sudo patch -p1 < linuxfb_swapRGB_2.patch #成功打上补丁文件
>>>>
Hunk #1 succeeded at 58 (offset -11 lines).
Hunk #2 succeeded at 155 (offset -11 lines).
Hunk #3 succeeded at 171 (offset -11 lines).
Hunk #4 succeeded at 187 (offset -11 lines).
Hunk #5 succeeded at 199 (offset -11 lines).
Hunk #6 succeeded at 208 (offset -11 lines).
Hunk #7 succeeded at 222 (offset -11 lines).
Hunk #8 succeeded at 234 (offset -11 lines).
Hunk #9 succeeded at 291 (offset -18 lines).
Hunk #10 succeeded at 377 (offset -18 lines).
Hunk #11 succeeded at 423 (offset -33 lines).
patching file src/plugins/platforms/linuxfb/qlinuxfbscreen.h
Hunk #1 succeeded at 69 (offset -7 lines).
<<<<
Qt5.5.1 configure编译选项,在这里不再介绍。
配置生成make文件时不报错,就可以make了。
$ cd qt-everywhere-opensource-src-5.5.1/
$ sudo ./configure \
-prefix /opt/qte5.5.1 \
-confirm-license \
-opensource \
-shared \
-release \
-make libs \
-xplatform linux-arm-gnueabi-g++ \
-optimized-qmake \
-pch \
-qt-sql-sqlite \
-qt-libjpeg \
-qt-libpng \
-qt-zlib \
-no-opengl \
-no-sse2 \
-no-openssl \
-no-cups \
-no-glib \
-no-dbus \
-no-xcb \
-no-xcursor -no-xfixes -no-xrandr -no-xrender \
-no-separate-debug-info \
-no-fontconfig \
-nomake examples -nomake tools -nomake tests -no-iconv \
-tslib \
-I/opt/tslib/include \
-L/opt/tslib/lib
$ sudo mkdir /opt/qte5.5.1 #在主机/opt目录下创建qte5.5.1目录
$ make -j4 #-j 4 表示4个线程同时编译,减少编译时间
$ sudo make install #安装Qt
$ cd /opt/qte5.5.1/bin
$ ./qmake -v #查看Qt,编译成功
>>>>
QMake version 3.0
Using Qt version 5.5.1 in /opt/qte5.5.1/lib
<<<<
1、
Makefile:46934: recipe for target '.obj/qpdf.o' failed
make[3]: *** [.obj/qpdf.o] Error 1
解决:去掉-qreal float选项。
2、
make[3]: Leaving directory '/home/jonny/qt/qt-everywhere-opensource-src-5.5.1/qtbase/src/gui'
Makefile:392: recipe for target 'sub-gui-make_first' failed
make[2]: *** [sub-gui-make_first] Error 2
make[2]: Leaving directory '/home/jonny/qt/qt-everywhere-opensource-src-5.5.1/qtbase/src'
Makefile:45: recipe for target 'sub-src-make_first' failed
make[1]: *** [sub-src-make_first] Error 2
make[1]: Leaving directory '/home/jonny/qt/qt-everywhere-opensource-src-5.5.1/qtbase'
Makefile:72: recipe for target 'module-qtbase-make_first' failed
make: *** [module-qtbase-make_first] Error 2
解决:此错误是找不到 -lqtpcre,这是Qt5.5.1的QTBUG-60496,
删掉qt5源代码,重新解压编译,即可编译通过。
3、大多数的报错都是编译器路径有问题导致的,检查qmake.conf文件。
至此,Qt5.5.1交叉编译完成。
补丁文件linuxfb_swapRGB_2.patch
>>>>
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
index 72d5833..5654e5f 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
@@ -69,6 +69,11 @@
QT_BEGIN_NAMESPACE
+typedef struct {
+ QImage::Format format;
+ bool swapRgb;
+} FbFormat;
+
static int openFramebufferDevice(const QString &dev)
{
int fd = -1;
@@ -161,12 +166,14 @@ static QSizeF determinePhysicalSize(const fb_var_screeninfo &vinfo, const QSize
return QSize(mmWidth, mmHeight);
}
-static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth)
+static FbFormat determineFormat(const fb_var_screeninfo &info, int depth)
{
const fb_bitfield rgba[4] = { info.red, info.green,
info.blue, info.transp };
- QImage::Format format = QImage::Format_Invalid;
+ FbFormat fbFormat;
+ fbFormat.format = QImage::Format_Invalid;
+ fbFormat.swapRgb = false;
switch (depth) {
case 32: {
@@ -175,11 +182,12 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth)
const fb_bitfield abgr8888[4] = {{0, 8, 0}, {8, 8, 0},
{16, 8, 0}, {24, 8, 0}};
if (memcmp(rgba, argb8888, 4 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_ARGB32;
+ fbFormat.format = QImage::Format_ARGB32;
} else if (memcmp(rgba, argb8888, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB32;
+ fbFormat.format = QImage::Format_RGB32;
} else if (memcmp(rgba, abgr8888, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB32;
+ fbFormat.format = QImage::Format_RGB32;
+ fbFormat.swapRgb = true;
// pixeltype = BGRPixel;
}
break;
@@ -190,9 +198,10 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth)
const fb_bitfield bgr888[4] = {{0, 8, 0}, {8, 8, 0},
{16, 8, 0}, {0, 0, 0}};
if (memcmp(rgba, rgb888, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB888;
+ fbFormat.format = QImage::Format_RGB888;
} else if (memcmp(rgba, bgr888, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB888;
+ fbFormat.format = QImage::Format_RGB888;
+ fbFormat.swapRgb = true;
// pixeltype = BGRPixel;
}
break;
@@ -201,7 +210,7 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth)
const fb_bitfield rgb666[4] = {{12, 6, 0}, {6, 6, 0},
{0, 6, 0}, {0, 0, 0}};
if (memcmp(rgba, rgb666, 3 * sizeof(fb_bitfield)) == 0)
- format = QImage::Format_RGB666;
+ fbFormat.format = QImage::Format_RGB666;
break;
}
case 16: {
@@ -210,9 +219,10 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth)
const fb_bitfield bgr565[4] = {{0, 5, 0}, {5, 6, 0},
{11, 5, 0}, {0, 0, 0}};
if (memcmp(rgba, rgb565, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB16;
+ fbFormat.format = QImage::Format_RGB16;
} else if (memcmp(rgba, bgr565, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB16;
+ fbFormat.format = QImage::Format_RGB16;
+ fbFormat.swapRgb = true;
// pixeltype = BGRPixel;
}
break;
@@ -223,9 +233,10 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth)
const fb_bitfield bgr1555[4] = {{0, 5, 0}, {5, 5, 0},
{10, 5, 0}, {15, 1, 0}};
if (memcmp(rgba, rgb1555, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB555;
+ fbFormat.format = QImage::Format_RGB555;
} else if (memcmp(rgba, bgr1555, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB555;
+ fbFormat.format = QImage::Format_RGB555;
+ fbFormat.swapRgb = true;
// pixeltype = BGRPixel;
}
break;
@@ -234,19 +245,19 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth)
const fb_bitfield rgb444[4] = {{8, 4, 0}, {4, 4, 0},
{0, 4, 0}, {0, 0, 0}};
if (memcmp(rgba, rgb444, 3 * sizeof(fb_bitfield)) == 0)
- format = QImage::Format_RGB444;
+ fbFormat.format = QImage::Format_RGB444;
break;
}
case 8:
break;
case 1:
- format = QImage::Format_Mono; //###: LSB???
+ fbFormat.format = QImage::Format_Mono; //###: LSB???
break;
default:
break;
}
- return format;
+ return fbFormat;
}
static int openTtyDevice(const QString &device)
@@ -298,7 +309,7 @@ static void blankScreen(int fd, bool on)
}
QLinuxFbScreen::QLinuxFbScreen(const QStringList &args)
- : mArgs(args), mFbFd(-1), mBlitter(0)
+ : mArgs(args), mFbFd(-1), mBlitter(0), mSwapRgb(false)
{
}
@@ -384,7 +395,9 @@ bool QLinuxFbScreen::initialize()
mBytesPerLine = finfo.line_length;
QRect geometry = determineGeometry(vinfo, userGeometry);
mGeometry = QRect(QPoint(0, 0), geometry.size());
- mFormat = determineFormat(vinfo, mDepth);
+ FbFormat fbFormat = determineFormat(vinfo, mDepth);
+ mFormat = fbFormat.format;
+ mSwapRgb = fbFormat.swapRgb;
mPhysicalSize = determinePhysicalSize(vinfo, userMmSize, geometry.size());
// mmap the framebuffer
@@ -443,8 +456,15 @@ QRegion QLinuxFbScreen::doRedraw()
mBlitter = new QPainter(&mFbScreenImage);
QVector rects = touched.rects();
- for (int i = 0; i < rects.size(); i++)
- mBlitter->drawImage(rects[i], *mScreenImage, rects[i]);
+ for (int i = 0; i < rects.size(); i++) {
+ if (mSwapRgb) {
+ mBlitter->drawImage(rects[i], mScreenImage->rgbSwapped(), rects[i]);
+ }
+ else {
+ mBlitter->drawImage(rects[i], *mScreenImage, rects[i]);
+ }
+
+ }
return touched;
}
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
index 32cd263..3a149a5 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
@@ -76,6 +76,7 @@ private:
} mMmap;
QPainter *mBlitter;
+ bool mSwapRgb;
};
QT_END_NAMESPACE
<<<<