Ubuntu20 交叉编译 Qt4.8 报错处理

1. 版本说明

操作系统:Ubuntu20.04 64位
交叉工具链:gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi
Qt版本:qt-everywhere-opensource-src-4.8.7

2. Ubuntu20.04 交叉编译 qt4.8.7 版本大致过程

2.1. 交叉编译 openssl1.0.1q

2.1.1. 配置
$ CC=arm-linux-gnueabi-gcc ./config no-asm no-async shared --prefix=/opt/imx6/openssl1.0.1q
2.1.2. make & install

打开Makefile文件删除-m64字样。

$ make -j4
$ make install

2.2. 交叉编译 tslib1.21

2.2.1. 安装依赖

tslib 依赖

$ sudo apt-get install autoconf 
$ sudo apt-get install automake 
$ sudo apt-get install libtool 
$ sudo apt-get install g++ 

qt 依赖

$ sudo apt-get install libc6-dev:i386 
$ sudo apt-get install build-essential 
$ sudo apt-get install gcc-multilib 
2.2.2. 解压后编译安装
$ ./configure --prefix=/opt/imx6dl/tslib1.4 --host=arm-linux-gnueabi CC=arm-linux-gcc --enable-shared --enable-static

$ make && make install

2.3. 交叉编译 qt4.8.7

2.3.1. 提取Qt4.8.7源代码
$ tar -zxvf qt-everywhere-opensource-src-4.8.7.tar.gz
2.3.2. 修改 mkspeces/qws/linux-arm-gnueabi-g++/qmake.conf
#
# qmake configuration for building with arm-linux-gnueabi-g++
#

include(../../common/linux.conf)
include(../../common/gcc-base-unix.conf)
include(../../common/g++-unix.conf)
include(../../common/qws.conf)

# modifications to g++.conf
QMAKE_CC                = arm-linux-gnueabi-gcc -lts -lssl -lcrypto		# 此四项去掉none再增加参数
QMAKE_CXX               = arm-linux-gnueabi-g++ -lts -lssl -lcrypto
QMAKE_LINK              = arm-linux-gnueabi-g++ -lts -lssl -lcrypto
QMAKE_LINK_SHLIB        = arm-linux-gnueabi-g++ -lts -lssl -lcrypto

# modifications to linux.conf
QMAKE_AR                = arm-linux-gnueabi-ar cqs						# 此三项去掉none
QMAKE_OBJCOPY           = arm-linux-gnueabi-objcopy
QMAKE_STRIP             = arm-linux-gnueabi-strip

QMAKE_INCDIR                +=/opt/imx6/tslib1.21/include				## 此四项增加
QMAKE_INCDIR                +=/opt/imx6/openssl1.0.1q/include
QMAKE_LIBDIR                +=/opt/imx6/tslib1.21/lib
QMAKE_LIBDIR                +=/opt/imx6/openssl1.0.1q/lib

load(qt_config)
2.3.3. 新增 autoConfigure.sh 脚本并执行
#!/usr/bin/env bash
./configure -opensource -v \
	-confirm-license \
	-embedded arm \
	-release -shared \
	-depths 16,18,24,32 \
	-optimized-qmake \
	-no-pch \
	-qt-sql-sqlite \
	-qt-libjpeg \
	-qt-zlib \
	-qt-libpng \
	-fontconfig \
	-qt-freetype \
	-little-endian \
	-no-qt3support \
	-no-libtiff -no-libmng \
	-no-opengl \
	-no-mmx -no-sse -no-sse2 \
	-no-3dnow \
	-no-webkit \
	-no-qvfb \
	-no-cups \
	-nomake examples \
	-nomake demos \
	-nomake docs \
	-qt-mouse-tslib \
	-qt-mouse-pc \
	-qt-gfx-transformed \
	-openssl-linked \
	-xplatform qws/linux-arm-gnueabi-g++ \
	-prefix /opt/imx6dl/qt-4.8.7-arm \
	-I /opt/imx6dl/openssl1.0.1q/include \
	-L /opt/imx6dl/openssl1.0.1q/lib \
	-I /opt/imx6dl/tslib1.21/include \
	-L /opt/imx6dl/tslib1.21/lib
2.3.4. make -j12 && make install

注意:编译过程出现 has no member named错误,依据 3 进行处理后编译。

3. has no member named 报错处理

make时编译错误如下:

dialogs/qpagesetupdialog_unix.cpp:276:12: 错误: ‘class Ui::QPageSetupWidget’ has no member named ‘topMargin’
     widget.topMargin->setSuffix(suffix);
            ^
dialogs/qpagesetupdialog_unix.cpp:277:12: 错误: ‘class Ui::QPageSetupWidget’ has no member named ‘bottomMargin’
     widget.bottomMargin->setSuffix(suffix);
            ^
dialogs/qpagesetupdialog_unix.cpp:278:12: 错误: ‘class Ui::QPageSetupWidget’ has no member named ‘leftMargin’
     widget.leftMargin->setSuffix(suffix);
            ^
... ...
make[1]: *** [Makefile:133419:.obj/release-shared-emb-arm/qpagesetupdialog_unix.o] 错误 1
make[1]: *** 正在等待未完成的任务....
dialogs/qfiledialog.cpp: 在成员函数‘QByteArray QFileDialog::saveState() const’中:
dialogs/qfiledialog.cpp:431:33: 错误: ‘class Ui_QFileDialog’ has no member named ‘treeView’
     stream << d->qFileDialogUi->treeView->header()->saveState();
                                 ^
dialogs/qfiledialog.cpp: 在成员函数‘bool QFileDialog::restoreState(const QByteArray&)’中:
dialogs/qfiledialog.cpp:487:49: 错误: ‘class Ui_QFileDialog’ has no member named ‘treeView’
     QHeaderView *headerView = d->qFileDialogUi->treeView->header();
                                                 ^
dialogs/qfiledialog.cpp: 在成员函数‘void QFileDialogPrivate::retranslateStrings()’中:
dialogs/qfiledialog.cpp:578:46: 错误: ‘class Ui_QFileDialog’ has no member named ‘treeView’
     QList<QAction*> actions = qFileDialogUi->treeView->header()->actions();
                                              ^
... ...
dialogs/qfiledialog.cpp: 在成员函数‘QModelIndex QFileDialogPrivate::rootIndex() const’中:
dialogs/qfiledialog.cpp:1412:39: 错误: ‘class Ui_QFileDialog’ has no member named ‘listView’
     return mapToSource(qFileDialogUi->listView->rootIndex());
                                       ^
dialogs/qfiledialog.cpp: 在成员函数‘QAbstractItemView* QFileDialogPrivate::currentView() const’中:
dialogs/qfiledialog.cpp:1418:73: 错误: ‘class Ui_QFileDialog’ has no member named ‘listView’
     if (qFileDialogUi->stackedWidget->currentWidget() == qFileDialogUi->listView->parent())
                                                                         ^
dialogs/qfiledialog.cpp:1419:31: 错误: ‘class Ui_QFileDialog’ has no member named ‘listView’
         return qFileDialogUi->listView;
                               ^
dialogs/qfiledialog.cpp:1420:27: 错误: ‘class Ui_QFileDialog’ has no member named ‘treeView’
     return qFileDialogUi->treeView;
                           ^
... ...
make[1]: *** [Makefile:135520:.obj/release-shared-emb-arm/qfiledialog.o] 错误 1
make[1]: 离开目录“/opt/imx6dl/tool/qt-everywhere-opensource-src-4.8.7/src/gui”
make: *** [Makefile:381:sub-gui-make_default-ordered] 错误 2

3.1. 报错分析

查看 src/gui/dialogs/qpagesetupdialog_unix.cpp 文件

报错处:
276     widget.topMargin->setSuffix(suffix);
277     widget.bottomMargin->setSuffix(suffix);
278     widget.leftMargin->setSuffix(suffix);
widget 创建处:
239 	void QPageSetupDialogPrivate::init()
240 	{
241     	Q_Q(QPageSetupDialog);
242 
243    		widget = new QPageSetupWidget(q);

查看 src/gui/dialogs/qpagesetupwidget.ui 文件(QPageSetupWidget对应ui文件)

查找到 topMargin 位置
190		<widget class="QDoubleSpinBox" name="topMargin" >
191     	<property name="toolTip" >
192         	<string>top margin</string>
193			</property>

查看 src/gui/.uic/release-shared-emb-arm/ui_qpagesetupwidget.h 文件(QPageSetupWidget对应头文件)

未查找到 topMargin 成员变量

应该是 ui 文件转换成头文件时出了问题。

查看 qpagesetupwidget.ui 文件的处理
$ grep -rn "qpagesetupwidget.ui" *
src/gui/Makefile:52073:	/opt/imx6dl/tool/qt-everywhere-opensource-src-4.8.7/bin/uic dialogs/qpagesetupwidget.ui -o .uic/release-shared-emb-arm/ui_qpagesetupwidget.h

依据 Makefile 中处理方式,用 uic 命令处理两个 ui 文件。

发现 uic 处理文件,有告警。且告警的 成员变量 未生成到对应的头文件。
$ ./qt-everywhere-opensource-src-4.8.7/bin/uic qpagesetupwidget.ui -o ui_qpagesetupwidget.h
qpagesetupwidget.ui: Warning: Buddy assignment: 'paperSize' is not a valid widget.
qpagesetupwidget.ui: Warning: Buddy assignment: 'paperWidth' is not a valid widget.
qpagesetupwidget.ui: Warning: Buddy assignment: 'paperHeight' is not a valid widget.
qpagesetupwidget.ui: Warning: Buddy assignment: 'paperSource' is not a valid widget.
$ ./qt-everywhere-opensource-src-4.8.7/bin/uic qfiledialog.ui -o ui_qfiledialog.h 
qfiledialog.ui: Warning: Tab-stop assignment: 'lookInCombo' is not a valid widget.
qfiledialog.ui: Warning: Tab-stop assignment: 'backButton' is not a valid widget.
qfiledialog.ui: Warning: Tab-stop assignment: 'forwardButton' is not a valid widget.
qfiledialog.ui: Warning: Tab-stop assignment: 'toParentButton' is not a valid widget.
qfiledialog.ui: Warning: Tab-stop assignment: 'newFolderButton' is not a valid widget.
qfiledialog.ui: Warning: Tab-stop assignment: 'listModeButton' is not a valid widget.
qfiledialog.ui: Warning: Tab-stop assignment: 'detailModeButton' is not a valid widget.
qfiledialog.ui: Warning: Tab-stop assignment: 'listView' is not a valid widget.
qfiledialog.ui: Warning: Tab-stop assignment: 'fileNameEdit' is not a valid widget.
qfiledialog.ui: Warning: Tab-stop assignment: 'fileTypeCombo' is not a valid widget.
qfiledialog.ui: Warning: Tab-stop assignment: 'buttonBox' is not a valid widget.
qfiledialog.ui: Warning: Tab-stop assignment: 'treeView' is not a valid widget.

3.2. qt uic

$ ./qt-everywhere-opensource-src-4.8.7/bin/uic -help
Qt User Interface Compiler version 4.8.7
Usage: /opt/imx6dl/tool/qt-everywhere-opensource-src-4.8.7/bin/uic [options] <uifile>

  -h, -help                 display this help and exit
  -v, -version              display version
  -d, -dependencies         display the dependencies
  -o <file>                 place the output into <file>
  -tr <func>                use func() for i18n
  -p, -no-protection        disable header protection
  -n, -no-implicit-includes disable generation of #include-directives
                            for forms generated by uic3
  -g <name>                 change generator

QT设计器设计的窗口部件,通过 uic 工具转换成C++代码。

对比 Ubuntu16.04 能正常编译的情况。再查找资料后,发现可能是Ubuntu20.04 自带GCC版本过高的问题。

3.3. 修改 ubuntu20.04 的 gcc、g++ 版本

3.3.1. 查看当前gcc版本
$ gcc -v
$ g++ -v

查看当前gcc命令的软链接

$ ls -liat /usr/bin/g++ 
531095 lrwxrwxrwx 1 root root 5 3月  20  2020 /usr/bin/gcc -> gcc-9
$ ls -liat /usr/bin/g++ 
531095 lrwxrwxrwx 1 root root 5 3月  20  2020 /usr/bin/g++ -> g++-9

ubuntu20.04 默认安装的 gcc9.4。

3.3.2. 安装gcc7并切换版本
sudo apt-get install gcc-7 g++-7

使用update-alternatives进行版本切换,输入以下命令:

# update-alternatives: --install 需要 <链接> <名称> <路径> <优先级>
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 100
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 50

sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 50

查看gcc的默认版本,可以看到当前默认gcc版本为7,即切换成功。

sudo update-alternatives --config gcc

查看当前gcc命令的软链接

$ ls -liat /usr/bin/gcc 
528697 lrwxrwxrwx 1 root root 21 3月  10 13:45 /usr/bin/gcc -> /etc/alternatives/gcc
$ ls -liat /usr/bin/g++
528698 lrwxrwxrwx 1 root root 21 3月  10 13:48 /usr/bin/g++ -> /etc/alternatives/g++
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值