UOS20编译Qt程序:搭环境、解决bug

本文详细介绍了在UOS操作系统上搭建Qt开发环境的步骤,包括安装Qt库和QtCreator,以及遇到的各类问题和解决方案。内容涵盖qmake问题、编译问题、链接问题和运行时错误,如库文件丢失、找不到头文件、枚举类型前向声明错误、预编译头文件问题等,并提供了相应的修复方法,如安装所需库、修改源码、调整.pro文件等。
摘要由CSDN通过智能技术生成

一、开发环境搭建

1.UOS专业版操作系统

  • 系统:UOS20
  • 处理器架构:X86_64

UOS系统下载链接:见此文

2.Qt库、QtCreator工具的安装

由于Qt支持跨平台,处理器架构均可以兼容,只需要把同样的代码在不同环境下进行编译即可。

首先UOS20进入 设置-通用-开发者模式。
然后在终端输入以下命令安装Qt:

 sudo apt update
 sudo apt-get install qtcreator qt5-default build-essential

安装内容包括:

  • Qt开发环境(头文件、动态库、Qmake等)
  • Qt IDE
  • gcc、g++、make、gdb…

检验Qt

 qmake --version

之后打开.pro文件就能显示Headers和Sources了。


现在因为bug2久久无法解决,我打算重装Qt了。结果意外发现用命令行安装了libcurl,解决了该问题。
安装教程也可参考这篇文章



二、UOS系统,X86架构,Qt编译遇到的bug:

事实上,只要厂商愿意,操作系统本身都是相对容易做到兼容多架构的。不容易兼容多架构的是应用程序和驱动。
应用程序通常需要用源代码重新编译一下才能支持新架构。当然这个前提是有源代码。

(一)qmake问题

1.qmake报错:警告:覆盖关于目标“moc_xxx”的配方 (overriding recipe for target'moc_xxx')
在这里插入图片描述
原因:.pro文件中重复有文件重复导入
解决:认真检查HEADERS += 和SOURCES += 后面是否有把同一个文件多次导入的情况。
我的问题的具体解决:(每个人重复的文件肯定不一样,仅供参考)
把最下方#Default里面默认平台导入的内容注释掉,与unix系统导入的重复了
在这里插入图片描述

(二)编译问题

1.库文件丢失:用命令行安装 sudo apt-get install 需要的库名/lib需要的库名

<xercesc/dom/DOM.h> file not found (后记:不对,在WIndows里缺少这些文件,是因为.pro文件里的路径改了。)
写了写路径,莫名其妙就解决了。

<curl/curl.h> file not found
INCLUDEPATH += 写路径,HEADERS +=头文件,命令行终端sudo apt-get install curl,上官网下载包并解压添加路径(此文)都不行
解决:

sudo apt-get install curl
sudo apt-get install libcurl4-openssl-dev

总结:curl和libcurl不是一回事。
curl是命令行工具,可以通过shell或脚本来运行curl。curl底层所使用的库是libcurl。
libcurl是一个库,通常与别的程序绑定在一起使用,如命令行工具curl就是封装了libcurl库。所以我们也可以在你自己的程序或项目中使用libcurl以获得类似CURL的强大功能。接下来将要介绍的PHP扩展就是对curl的一个封装。

<cups/cups.h> file not found

CUPS(Common Unix Printing System),通用Unix打印系统,是苹果公司所有,一个打印集成服务。是类Unix系統上的通用打印系统,支持本地、远程打印。

解决:同样,除了要安装cups,还要安装libcups

sudo apt-get install cups
sudo apt-get install libcups2-dev

以上2.全部推翻。就是路径问题。以前有的INCLUDEPATH = $${MY_HOME_LIB}/include。但是再往前声明的 MY_HOME_LIB = /home/indigo/local的路径已经变了,应该改为MY_HOME_LIB =/home/edward/indigo/local(看来以前的用户名是indigo)
这样,包含boost和local文件夹里包含 xerces、curl库、cups库,就找到了,还是路径问题。要注意这种$${ }指代路径是否出错

#include <io.h> file not found

将程序替换为: #include <sys/io.h>

#include <process.h> file not found

process.h是vc中的多线程函数,linux下没有该函数!用pthread.h替换

将④和⑤合写为

#ifdef _Win32
	#include <io.h>
	#include <process.h>
#else   //支持UOS
	#include <sys/io.h>
	#include <pthread.h>
#endif

snmp缺失
解决:

sudo apt install libsnmp*dev

简单网络管理协议(SNMP) 是专门设计用于在 IP
网络管理网络节点(服务器、工作站、路由器、交换机及HUBS等)的一种标准协议,它是一种应用层协议。



2.use of enum 'asn_dec_rval_code_e' without previous declaration

错误原因:gcc编译器不支持枚举类型的前向声明。但是MSVC是支持的。代码从MSVC编译的,放到gcc编译器下就会报这个错。

在C++11之前,C++标准是不支持枚举类型的前向声明的。我说出这个结论,肯定有用msvc的童鞋不愿意了:口胡,MSVC明明就可以对枚举类型前向声明,下面这样的前向声明在MSVC下好好的,没有任何问题。

enum E;

因为C++98标准中没有⽀持枚举类型前向声明,所以就不能保证上⾯的写法对任何编译器都⾏。为什么枚举类型不能被前向声明呢?
因为编译器⽆法知道枚举变量所需的存储空间。 在编译期,C ++编译器要为变量保留存储空间。 如果所有可见的都是前向声明,那么编译
器⽆法知道选择哪种存储⼤⼩ - 它可能是char,word或int,或其他。

在C++11中通过下⾯的语法指定了变量存储空间⼤⼩,就可以⽀持前向声明了:

解决:声明枚举类型的大小就ok了。或者不前向声明,直接把实现也拉过来。

enum E :unsignedint;



3.extra qualification ‘Hyeofd::’ on member ‘ofdToPdf’ [-fpermissive]
错误写法:
1.在类的定义(或者头文件定义)中写了void Hyeofd::ofdToPdf(); 在类实现中写了 void ofdToPdf(){};
2.在类的定义(或者头文件定义)中写了void Hyeofd::ofdToPdf(); 在类实现中写了void Hyeofd::ofdToPdf();
正确写法:
头文件定义中写void ofdToPdf(); 在类实现中写了void Hyeofd::ofdToPdf();

一句话,本身已经在类里声明了,声明的时候还带类名+作用域限定符干嘛??



4.无法识别usleep()、close()、socklen_t (这些是属于<unistd.h>的函数)
原因:说明<unistd.h>缺失。是因为我的UOS安装了2个QtCreator,调用Qt库的时候,相互冲突了。官网下载的.run文件,解压出QtCreator5.12(Enterprise)和命令行下载的QtCreator5.11。
解决方法:把Qt5.12的文件名改成Qt5.12backup。这样寻找路径的时候就打不开Qt5.12了。






4.1 错误1: error: ‘socklen_t’ does not name a type; did you mean ‘locale_t’? typedef socklen_t SocketLengthType;
在这里插入图片描述
分析:能跑的UOS,点开这个文件,这里是 error:unknown type socklen_t。但是编译没有报错,直接能运行。
能跑的Windows,直接进的#else里的typedef int SocketLengthType。直接没有错误。
两三天了,不知道怎么解决。崩溃。先干着别的了。
解决:[暴力修改源码] UOS下,注释掉宏,只保留typedef int SocketLengthType,大家都走int这条路。不报错了。再点编译,报了下面第二个错误:

错误2:error: declaration of ‘int strcasecmp(const char*, const char*) throw ()’ has a different exception specifier extern int strcasecmp (const char *__s1, const char *__s2)
在这里插入图片描述
解决:print.h的头文件导入顺序有问题。换成旧版本的顺序。

错误3:

/usr/bin/ld: RxfFile.o: in function `CRxfFile::SerializeTxt()':
RxfFile.cpp:(.text+0x458): undefined reference to `COfdDoc::COfdDoc(std::vector<unsigned char, std::allocator<unsigned char> > const&)'
collect2: error: ld returned 1 exit status

分析:undefined reference to 这就是典型的声明与实现不匹配。找到位置使得声明和实现匹配(都存在或都不存在)即可。








5.Unknown module(s) in QT: svg
原因:缺少组件svg
解决:

sudo apt-get install libqt5svg5-dev

或者,泛写

sudo apt-get install libqt5*dev



(三)链接问题

原因:Windows下编译的静态库为.lib,动态库为.so。而Linux下的静态库为.a,动态库为.so。需要重新编译第三方库。

一)链接所需要的静态库/动态库找不到

1.libsnmp++.a 找不到
原因:同上,只有libsnmp.lib,是Windows下的静态库。

需要在Linux下编译snmp++库

解决:
1)下载:上官网。https://www.agentpp.com/download.html。找到SNMP++,下载。在这里插入图片描述
2)解压
图形化界面点解压,或者终端用tar -zxvf命令

tar -zxvf libdes-l-4.01a.tar.gz 
tar -zxvf snmp++v3.4.10.tar.gz

3)make

cd libdes
make -f Makefile
cp libdes.a /usr/lib

cd snmp++/src
make -f Makefile.linux   //关键就这一条。然后在lib文件夹下得到编译出来的库,拷贝到所需要的位置
cd ../lib
cp * /usr/lib

注意:在终端执行 make -f Makefile.linux时可能会报错:
make: *** 没有规则可制作目标“…/include/system/libsnmp.h”,由“eventlist.o” 需求。 停止。
解决:把libsnmp.h复制到它要求的路径下(自己在/include下面建立system,里面放入libsnmp.h),就可以make了


2.cannot find -lxerces-c
原因:同上,需要在Linux下编译xerces-c库
解决:
1)下载:上官网,https://xerces.apache.org/xerces-c/download.cgi ,在Download里下载
在这里插入图片描述
2)解压,并进入文件夹
3) 配置和make

./configure --prefix=/home/edward/Downloads/lib              //预设路径
 make all
 make install              //放到预设的路径上。显示bin、include、lib文件夹

在这里插入图片描述

3.cannot find -ljsoncpp
解决:对jsoncpp进行编译

1)下载jsoncpp-src-0.5.0.7z
2)安装scons

 sudo apt-get install scons

JsonCPP类库需要Scons编译器来编译,而Scons需要Python安装了才能使用。具体安装步骤请参见文件夹下的ReadMe文件。

3)解包jsoncpp:

tar -zxf jsoncpp-src-0.5.0.tar.gz

4)jsoncpp安装:

解包后进入其目录。输入以下命令:

 scons platform=linux-gcc  

就会安装成功

5)改名
上述已经完成jsoncpp的编译,在解压目录jsoncpp-src-0.5.0/libs/linux-gcc-4.8下可以看到生成了两个文件:
libjson_linux-gcc-4.8_libmt.a
libjson_linux-gcc-4.8_libmt.so
放到对应路径,改成需要的名字

二).o: in function * undefined reference to ** 未定义的引用

报错如图:
在这里插入图片描述
分析:
单纯这个报错内容来看,很经典的undefined reference to的报错,这个报错在调用第三方库的编程中,简直是家常便饭,代表的含义也很明确,就是找不到函数的定义。
用C++写代码的都知道,在C++中,代码是分为声明和定义的,声明就是告诉编译器有这个函数,换言之,就是个名字,而定义,就是具体这个函数的实现内容。
类似这个报错的,还会有一种报错是undeclared的报错,这大概就是函数声明的报错。

解决:
在这里插入图片描述
在QT中,可能是文件所在类在pro文件没有索引。
需要在.pro文件中检查SOURCES(HEADERS)是否忘记引用了报错的.cpp(.h)

但是直接在SOURECES += 和HEADERS+=里添加,会导致qmake报错


三)g++: error:   .o: No such file or directory

在这里插入图片描述
上一步改错的时候,把HEADERS += 和 SOURCE += 里加入了$$PWD。相当于要编译当前的文件夹。YR86_Linux就是我的整个文件夹的名字。

四、运行时错误

1.窗口显示问题:程序运行启动后卡住不动,窗口加载不出来:
用Debug模式对main()函数进行单步调试。我是发现有一个动态库没加载到,然后紧跟着判断动态库是否已加载的while循环就卡死在这了。在对应绝对路径放上需要的动态库.so后就通过了
在这里插入图片描述
208行没有加载到动态库。
Debug模式下,右侧变量名处,右键第一个 Add New Expression Value。把208行左侧变量加进来,发现是一个绝对路径(右侧一长串居然是一个地址)。然后把libxxx.so加到这个地址,就可以了。
在这里插入图片描述



2.程序crashed
在这里插入图片描述
网上都是说是因为有动态库没有链接,但是我在.pro文件和main.cpp里都静态或者动态加载了所有库。
崩溃了好久找不出问题,最后忍不住问了waters。说是配置语言的两个自己写的l18N,config文件夹,没有加。放在build(debug/release)目录下就好了。赶在交付日期当天2022.06.10解决了。

原因:没有相应的字体文件



3.预览模块可以以后(能用,但是编译还是报错),打印模块无法打印。打印机似乎能接收到打印信号,但是无法打印内容。

原因:通过XPDF读取PDF内容并转化为txt格式的过程中,可能会出现如下提示

xpdf:将pdf图片转化为txt文本

在这里插入图片描述

Error: Couldn't open cidToUnicode file '/data/home/edward/test/build-YeecohReader-unknown_4fc94b-Debug/config/config/chinese-simplified/Adobe-GB1.cidToUnicode'
Error: Unknown character collection 'Adobe-GB1'
Error: Couldn't find 'UniGB-UCS2-H' CMap file for 'Adobe-GB1' collection
Error: Unknown CMap 'UniGB-UCS2-H' for character collection 'Adobe-GB1'
Error: 
Unknown font tag 'Xi0'
Error (153116): No font in show
Error: Couldn't open cidToUnicode file '/data/home/edward/test/build-YeecohReader-unknown_4fc94b-Debug/config/config/chinese-simplified/Adobe-GB1.cidToUnicode'
Error: Unknown character collection 'Adobe-GB1'
Error: Couldn't find 'UniGB-UTF16-H' CMap file for 'Adobe-GB1' collection
Error: Unknown CMap 'UniGB-UTF16-H' for character collection 'Adobe-GB1'
Error: Unknown font tag 'AdobeHeitiStd-Regular'
Error (125578): No font in show

解决:查看config目录下的xpdfrc文件。查看路径。因为报错的时候有config/config,明显路径重复了。要在xpdfrc里删除多余的/config
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员爱德华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值