将 C++ Qt 程序移植至 Linux 系统
2017-03-09 18:03
429 查看
前言
Qt 的安装
选择对应版本
更改文件的属性使得其具有可执行性
执行程序
检查 Qt Creator 是否勾选
进入 Qt Creator
Qt 环境的配置
安装 gcc 或 g 编译器
编译器错误 ICE in gen_type_die_with_usage
更新 g
C 在 MSVC 与 GNU G上的不同之处
enum 的前置声明
size_t 与 stdsize_t
auto 推断函数返回值
函数返回数组问题
其他问题
初始化顺序 warning will be initialized after -Wreorder
替换 INT_MAX 和 INT_MIN
感想
在终端中切换目录至文件路径,之后执行
另附:该页的打开方式为:Qt Creator 的菜单栏 -> Tools -> Options -> Build & Run -> Compilers。安装后会自动识别并显示在 Auto-detected 一栏。
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
(注:在这里,我执行完这两个语句后依然提醒:
E: Unable to locate package g++-5
E: Couldn’t find any package by regex ‘g++-5’,
E: Unable to locate package gcc-5
E: Couldn’t find any package by regex ‘gcc-5’,
但是再次执行就成功了,所以如果一次没成功不妨多试几次,要是还是不行就再查找其他解决方案也不迟)
sudo apt-get install gcc-5 g++-5
还没完,还需要将新的 g++-5 链接至 Qt 所调用的 link 文件(这个东西就和快捷方式差不多):
sudo ln -s /usr/local/bin/gcc /usr/bin/gcc
sudo ln -s /usr/local/bin/g++ /usr/bin/g++
可以通过
再次编译,结果遗憾的是,编译器又再次返回了 usr/bin/ld: cannot find -lGL 的错误。再次上网查找,最终找到了通用的缺失 -lxxx 的解决方法:http://eminzhang.blog.51cto.com/5292425/1285705。对于我的环境而言而言,这个是系统缺失 libGL.so 的问题,也就是缺失 OpenGL 导致的问题。于是有:
(注:可能需要安装 apt-file 程序并更新它的数据:)
sudo apt-get install apt-file
apt-file update
apt-cache search libgl-dev (注:寻找哪个包中包含该库)
sudo apt-get install libgl1-mesa-dev(注:这是我的系统上返回的第一项)
最终配置大致为:
再次编译,几十秒内没有报错。
这种用法标准的 C++ 是不支持的。我猜想是微软扩充的结果。
对此有两种解决方法:
或者,在 C++11 或之后版本:
但是在跨平台时,我又发现实际上 size_t 是定义在 std 命名空间中的。根据查找,size_t 是定义于 vcruntime.h 的。很明显,这也是微软扩充的结果。所以,通用的写法应该是:
但是,根据编译器提示这个是 C++14 之后才支持的,由于不想再次更新 g++,替换为
在 VS 上编译成功,在 g++ 上失败。我本想使用 typedef 代替:
但编译仍然失败,最终经过查找,由于数组不支持复制,所以 C++ 不允许返回数组。经过 《C++ Primer》 的启发,我将它改为了尾置返回类型:
相比而言,确实清晰明了。
最后的最后,程序终于成功运行。
应改为:
但在当时,不知道为何,编译时报错:INT_MAX 与 INT_MIN 未定义。没办法,我将他们替换成了:
这是与平台无关的最大最小值。使用了位运算,具体实现请参考计算机组成原理。
另附:刚刚在 Linux 系统的 stdlib.h 中看到了 INT_MAX 与 INT_MIN 这两个宏定义。也就是说它们是 C 标准定义的。
接下来我的重点仍然在开头提到的游戏:https://github.com/lgasyou/SimpleSimulator。以上提到的改变均能在 Commits 中可以看到。欢迎讨论。
如果本文有错误的地方,欢迎大家指正。谢谢大家。
Qt 的安装
选择对应版本
更改文件的属性使得其具有可执行性
执行程序
检查 Qt Creator 是否勾选
进入 Qt Creator
Qt 环境的配置
安装 gcc 或 g 编译器
编译器错误 ICE in gen_type_die_with_usage
更新 g
C 在 MSVC 与 GNU G上的不同之处
enum 的前置声明
size_t 与 stdsize_t
auto 推断函数返回值
函数返回数组问题
其他问题
初始化顺序 warning will be initialized after -Wreorder
替换 INT_MAX 和 INT_MIN
感想
前言
前段时间,我一直在使用 Visual Studio 编写一个 C++ Qt 游戏小程序:https://github.com/lgasyou/SimpleSimulator。突然有一天,我想看看它的可移植性到底如何,于是我把它转化成 .pro 并移至了 Ubuntu 14.04 系统中,之后就开始了漫长的配置之旅。Qt 的安装
1. 选择对应版本
可以前往 Qt 的官方网站根据CPU架构类型和版本号的不同选择 qt-opensource-linux-CPU架构类型-任意版本号.run 下载,例如需在 32 位系统下下载版本号为 5.8.0 时的 Qt 则选择 qt-opensource-linux-x86-5.8.0.run。2. 更改文件的属性使得其具有可执行性:
刚刚下载的程序并不具有可执行性,还需要改变它的属性。在终端中切换目录至文件路径,之后执行
chmod +x qt-opensource-linux-CPU架构类型-任意版本号.run。
3. 执行程序
在终端中输入./qt-opensource-linux-CPU架构类型-任意版本号.run,例如
qt-opensource-linux-x86-5.8.0.run或是直接双击执行程序。
4. 检查 Qt Creator 是否勾选。
5. 进入 Qt Creator
安装完成,可以使用菜单栏的搜索功能搜索并进入 Qt Creator(Community)。如果需要可以选择将其固定至菜单栏之上。之后便进入了下一个环节。Qt 环境的配置
1. 安装 gcc 或 g++ 编译器
安装完成,我创立了一个 HelloWorld 程序,并开始编译。但是很不幸运,编译器返回了 “error while building deploying project” 的错误。我在网上找了很久,但是解决方法都与我的情况基本无关。直到好几天后,我突然发现我的 Compiler 配置里面竟然没有 C++ 的编译器!于是我又安装了 g++:sudo apt-get install g++。终于,可以开始编译了!但是没有10秒钟,我又遇到了第二个问题。
另附:该页的打开方式为:Qt Creator 的菜单栏 -> Tools -> Options -> Build & Run -> Compilers。安装后会自动识别并显示在 Auto-detected 一栏。
2. 编译器错误 ICE: in gen_type_die_with_usage
这次,编译器又返回了 ICE: in gen_type_die_with_usage, at dwarf2out.c:19484 的错误。我上网一查,这次竟然是编译器的 bug。是 g++ 版本的问题,需要更新。3. 更新 g++
根据这里的帖子,需要输入以下的命令来获取最新的g++:sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
(注:在这里,我执行完这两个语句后依然提醒:
E: Unable to locate package g++-5
E: Couldn’t find any package by regex ‘g++-5’,
E: Unable to locate package gcc-5
E: Couldn’t find any package by regex ‘gcc-5’,
但是再次执行就成功了,所以如果一次没成功不妨多试几次,要是还是不行就再查找其他解决方案也不迟)
sudo apt-get install gcc-5 g++-5
还没完,还需要将新的 g++-5 链接至 Qt 所调用的 link 文件(这个东西就和快捷方式差不多):
sudo ln -s /usr/local/bin/gcc /usr/bin/gcc
sudo ln -s /usr/local/bin/g++ /usr/bin/g++
可以通过
g++ --version查看版本判断是否成功
再次编译,结果遗憾的是,编译器又再次返回了 usr/bin/ld: cannot find -lGL 的错误。再次上网查找,最终找到了通用的缺失 -lxxx 的解决方法:http://eminzhang.blog.51cto.com/5292425/1285705。对于我的环境而言而言,这个是系统缺失 libGL.so 的问题,也就是缺失 OpenGL 导致的问题。于是有:
(注:可能需要安装 apt-file 程序并更新它的数据:)
sudo apt-get install apt-file
apt-file update
apt-cache search libgl-dev (注:寻找哪个包中包含该库)
sudo apt-get install libgl1-mesa-dev(注:这是我的系统上返回的第一项)
最终配置大致为:
再次编译,几十秒内没有报错。
C++ 在 MSVC 与 GNU G++上的不同之处
很遗憾,它不肯善罢甘休,很快,我又遇到了多个 Error。1. enum 的前置声明
之前有:namespace Gameconstants { enum BuildingTypes; }
这种用法标准的 C++ 是不支持的。我猜想是微软扩充的结果。
对此有两种解决方法:
// 直接包含头文件 #include "gameconstants.h" /* 使用 enum BuildingTypes */
或者,在 C++11 或之后版本:
// C++11 规定,枚举的前置声明需要指定成员类型,例如本例中指定为int。 // 同时,若是 enum class 类型,则可以不指定,使用默认类型 int。 namespace Gameconstants { enum BuildingTypes : int; }
2. size_t 与 std::size_t
以往,我都是直接使用 size_t 的:size_t member;
但是在跨平台时,我又发现实际上 size_t 是定义在 std 命名空间中的。根据查找,size_t 是定义于 vcruntime.h 的。很明显,这也是微软扩充的结果。所以,通用的写法应该是:
std::size_t member;
3. auto 推断函数返回值
我在 baseindustry.h 中有:const auto &machines() const { return this->machines_; }
但是,根据编译器提示这个是 C++14 之后才支持的,由于不想再次更新 g++,替换为
const std::vector<Machine *> &machines() const { return this->machines_; }
4. 函数返回数组问题
public: auto occupiedMap() const { return this->occupiedMap_; } private: bool occupiedMap_[100][100];
在 VS 上编译成功,在 g++ 上失败。我本想使用 typedef 代替:
typedef bool Array[100][100]; Array occupiedMap() const { return this->occupiedMap_; }
但编译仍然失败,最终经过查找,由于数组不支持复制,所以 C++ 不允许返回数组。经过 《C++ Primer》 的启发,我将它改为了尾置返回类型:
// 返回了数组的指针 auto occupiedMap() const -> const bool(*)[100] { return occupiedMap_; }
相比而言,确实清晰明了。
最后的最后,程序终于成功运行。
其他问题
1. 初始化顺序, warning: will be initialized after [-Wreorder]
当时由于某个类成员变动频繁,类的构造函数中的成员顺序与声明时不同,所以出现了这个错误。// 会返回 warning: memberOne will be initialized after [-Wreorder] class A { public: A() : memberOne(), memberTwo() { } private: Type memberTwo; Type memberOne; }
应改为:
// 没有报警 class B { public: B() : memberOne(), memberTwo() { } private: Type memberOne; Type memberTwo; }
2. 替换 INT_MAX 和 INT_MIN
在原版的代码中,我是这样写的#include <cstdlib> /* ... */ namespace GameConstants { const int integerMaximum = INT_MAX; const int integerMinimum = INT_MIN; }
但在当时,不知道为何,编译时报错:INT_MAX 与 INT_MIN 未定义。没办法,我将他们替换成了:
const int integerMinimum = (1 << (sizeof(int) * 8 - 1)); const int integerMaximum = (int)((unsigned)integerMinimum - 1);
这是与平台无关的最大最小值。使用了位运算,具体实现请参考计算机组成原理。
另附:刚刚在 Linux 系统的 stdlib.h 中看到了 INT_MAX 与 INT_MIN 这两个宏定义。也就是说它们是 C 标准定义的。
感想
能够成功运行,着实不易。虽然过程很艰难,不过通过这个过程也学到了不少干货,很值。接下来我的重点仍然在开头提到的游戏:https://github.com/lgasyou/SimpleSimulator。以上提到的改变均能在 Commits 中可以看到。欢迎讨论。
如果本文有错误的地方,欢迎大家指正。谢谢大家。
相关文章推荐
- [ARM Linux] [Qt] 移植Qt程序到ARM Linux上 (包括如何构建专业的PDA界面、phone界面)
- linux程序(C++)由32位移植到64位的过程,还在尝试中,大侠勿喷,多多指点啊。。。
- Linux系统如何写C/C++程序
- 在ARM开发板的嵌入式linux系统上运行的QT程序,必须得要在linux里用QT编吗
- Qt4.8.7 linux 程序移植到 Qt5.9 windows 记录过程
- arm-marvell-linux-gnueabi 交叉编译c/c++程序,并移植到android
- 在linux系统上搭建QT移植mini2440步骤
- Windows下C++程序移植到Linux上的几个问题及解决方法
- linux学习(三)如何在linux系统下利用vi编辑C/C++程序
- windows c++ 程序移植到Linux的一些要点
- linux系统下,c++程序,调用system命令失败,分析过程
- linux系统编译C++程序时头文件和库文件搜索路径
- Qt/Embedded在嵌入式Linux系统下的移植与应用
- Fedora 11中用MinGW编译Windows的Qt4程序(在Linux系统下编译Windows的程序)
- 将VC程序移植到Linux系统的几点经验心得
- aix 使用g++编译c++程序的编译选项 -- linux到aix移植经验
- 【Linux C调试笔记】Linux系统下借助mcheck实现c/c++程序的堆内存异常检查
- linux系统编译C++程序时头文件和库文件搜索路径
- win7C++程序移植到Linux出现的问题
- 移植LINUX的外围设备驱动到QNX系统,linux程序移植到QNX