本人使用的操作系统是Fedora24。
Linux下我们习惯了使用软件包管理器来安装我们需要的软件,比如Red Hat公司的Fedora、RHEL(Red Hat Enterprise Linux)和后来加入红帽的CentOS,使用rpm和yum来安装软件,Ubuntu使用apt-get来安装。 使用软件包管理器确实很方便,在联网的环境下,从下载到安装,以及自动关联软件的依赖项,并且一次安装所有依赖的软体包,为我们省去了很多繁琐的操作。这样确实很好,但是我们却失去了了解软件有哪些组成模块和依赖项的机会。下面我就要折腾一下,手动下载安装C++环境,摆托yum install gcc-c++
这种傻瓜式操作。手动下载安装还有一个好处就是为不能联网的机器安装软件。有时候,确实要这样做。
正式开始本文前,先交代几个东西的概念,以及它们之间的联系,还有大家(包括me)可能存在的疑问。
GNU是什么? GNU是由大名鼎鼎的自由软件之父Richard Stallman在1983年9月27日公开发起的一项计划,又称革努计划。GNU计划的目标是创建一套完全自由的操作系统。GNU是“GNU is Not Unix”的递归缩写,当然,我们可以把GNU理解成推动革奴计划的组织,一个自由软件组织。
GNU计划已经开发出了许多开源免费的工具软件供我们这些小白程序员使用,我所知道的就有C编译器gcc(GNU C Compiler),C++编译器g++(GNU C++ Compiler),CC++调试器gdb(GNU Debugger),文本编辑器Emacs,项目构建工具gnu make,系统shell bash(GNU shell)等等。最初的Linux内核也是以GNU通用公共许可证(GNU General Public License,GPL)发布的!
GNU是操作系统吗? 上面已经说了,GNU是一项致力于创建一套完全自由的操作系统的一项计划,因此GNU显然不是操作系统!
至于GNU有没有自己的操作系统,我不太清楚,但听说有个Hurd,但是没有流行起来啊!据说GNU自己的系统内核Hurd还在研发中。 不要把Linux当做GNU的一部分,Linux不是GNU组织开发的,Linux只是以GNU的开源协议GPL来发布的。 严格来说Linux不是一个完整的操作系统,只是一个系统内核。比如Linux发行版Debian使用linux内核就称为Debian/linux,用hurd内核就称为Debian/hurd。如果Hurd推出正式版的话,GNU/Hurd就是一个真正的完整的完全自由的操作系统。
有人也许还会问GNU/Linux是什么,这里说明一下,GNU 的系统内核Hurd尚未完成,所以 GNU 使用 Linux 作为其内核。GNU 和 Linux 以这样的方式组合成为 GNU/Linux 操作系统,所以 GNU/Linux是GNU以Linux作为内核而发布的一个操作系统。如果你的系统是GNU/Linux的话,使用uname -o
或者uname --operating-system
命令就可以查看系统的名称,我的就是GNU/Linux,如下图:
GCC是什么? GCC很容易和下面讲到的C语言编译器gcc弄混淆,也请大家注意。GCC(GNU Compiler Collection)是GNU编译器套件,包括C、C++、Objective-C、Fortran、Java、Ada和Go语言等的编译器,当然也包括了这些语言的库(如libstdc++、libgcj等等)。而gcc是GCC的一部分,即C语言编译器!
gcc是什么? gcc不是GCC,请大家注意。gcc(GNU C Compiler)是GNU开发的C语言编译器。是GCC的一部分。
gcc是不能用来编译C++代码的,也请大家注意!
g++是什么? g++(GNU C++ Compiler)是GNU开发的C++编译器,也是GCC的一部分。因为C++是C语言的扩充,很显然,g++是可以编译C语言的。
gcc能编译C++代码吗? 看了上面的说明,弄清楚gcc是什么,你就知道gcc是不能编译C++代码的!
安装C++开发环境需要安装两部分,第一部分是C++库,第二部分就是C++编译器g++。离线安装C++开发环境,首先你得有源代码或者对应的rpm或者deb软件包。有两种方法,第一种是编译GCC源码安装,第二种就是下载系统的软件包并安装。
第一种方法是下载编译安装GCC源码,需要下载各种依赖库,而且还需要系统中提前存在g++,我在尝试的过程中,在编译依赖库的时候,提示说未检测到g++。我编译GCC就是为了安装g++,现在提示我说没有g++,这不造成死循环了吗?所以无法继续下去,对于已经有g++的系统需要升级g++版本的话,可以参考下面的GCC的编译安装。
第二种方法是下载不同系列的Linux系统对应的g++编译好的二进制软件包进行安装。比如Red Hat系列的Fedora、CentOS和RHEL使用的rmp包,Ubuntu使用的deb包。本文就在Fedora24的环境下,下载软件包来安装C++开发环境。
本文使用GNU C++来搭建Linux下C++开发环境,所以首先得下载安装C++库与C++的编译器g++。上面说了GCC是包含g++和C++的库,所以我们要下载和安装GCC!
下载东西有时也不是想象的那么简单,我们下载东西一定要坚持一个原则:从官网下载!网上很多站点都会有杂七杂八的资源可供下载,但是下载了之后我们都不知道这个站点的东西是从哪里来的,有没有被第三方修改,以及是不是官方的最新版本等等。所以,为了保证下载的软件的质量和可靠性,我们还是要去官网下载吧!
上官网GCC官网,找到最新的released GCC点击进入,一步一步的查找,发现GCC隐藏的够深,有两个站点可以下载,一个是GCC mirror sites,一个是GCC svn server。我这里是从镜像站点下载,GCC 6.1的下载地址见:GCC 下载。我选择的是今天2016.07.05最新版本gcc-6.1.0.tar.gz 。
下载GCC依赖的四个库: 点击下载:GMP库 或者GMP官网,对应GCC-6.1.0,我下载的是gmp-6.1.1.tar.bz2。 点击下载:MPFR库或者MPFR官网,我下载的是mpfr-3.1.4.tar.gz。 点击下载:MPC库或者MPC官网,我下载的是mpc-1.0.3.tar.gz。 点击下载:[ISL库](ftp://gcc.gnu.org/pub/gcc/infrastructure/ and download),我下载的是isl-0.16.tar.bz2。
关于依赖关系,MPFR依赖GMP,MPC依赖GMP和MPFR,GCC依赖上面四个库,所以推荐的编译安装顺序是GMP->MPFR->MPC->ISL->GCC。
关于GMP、MPFR、MPC和ISL是什么库,这里简要说明一下: (1)GMP:计算任意精度的数学库, 包括支持整数,有理数和浮点。GMP包括大量的接口函数.-GMP is a free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating point numbers. There is no practical limit to the precision except the ones implied by the available memory in the machine GMP runs on. GMP has a rich set of functions, and the functions have a regular interface.
(2)MPFR: 一个多精度高效的浮点计算C语言库, 基于GMP。-The MPFR library is a C library for multiple-precision floating-point computations with correct rounding. MPFR has continuously been supported by the INRIA and the current main authors come from the CACAO and Arénaire project-teams at Loria (Nancy, France) and LIP (Lyon, France) respectively see more on the credit page. MPFR is based on the GMP multiple-precision library.
(3)MPC:一个支持高精度复数的算术运算的C库,并能正确的进行结果舍入。它扩展为IEEE-754标准对固定精度实浮点数到复数的转换,对于每一个操作都定义了明确的语义。与此同时,高精度操作的速度是一个主要的设计目标。 Mpc is a C library for the arithmetic of complex numbers with arbitrarily high precision and correct rounding of the result. It extends the principles of the IEEE-754 standard for fixed precision real floating point numbers to complex numbers, providing well-defined semantics for every operation. At the same time, speed of operation at high precision is a major design goal.
(4)ISL是用于操作集合和线性约束下的整数点的关系的库,支持集合的交,并和补操作。 isl is a library for manipulating sets and relations of integer points bounded by linear constraints. Supported operations on sets include intersection, union, set difference, emptiness check, convex hull, (integer) affine hull, integer projection, and computing the lexicographic minimum using parametric integer programming. It also includes an ILP solver based on generalized basis reduction and operations geared towards polyhedral compilation such as dependence analysis, scheduling, and AST generation.
使用tar解压下载的gcc-6.1.0.tar.gz和依赖库。按照上面的说的编译安装顺序进行,具体参见Compiling GCC 6 on OS X。这是我花了很长时间千辛万苦找到的资料,很详细,一定要看。因为本人系统中没有已经装好的g++,所以不能顺利的安装,大家如果找到了在在没有g++的机器上编译安装GCC的办法,请留言告知,谢谢!
所以下面我就采用下载Fedora的gcc-g++的安装包来安装C++开发环境。
首先下载gcc-c++安装包,下载地址:gcc-c++。
我下载的是针对Fedora24发布的gcc-c++-6.1.1-3.fc24.x86_64.rpm,大家可选择自己对应的系统进行下载。 安装命令如下:
sudo rpm -ivh gcc-c++-6.1.1-3.fc24.x86_64.rpm
结果提示如下错误: gcc = 6.1.1-3.fc24 被 gcc-c++-6.1.1-3.fc24.x86_64 需要 libstdc++ = 6.1.1-3.fc24 被 gcc-c++-6.1.1-3.fc24.x86_64 需要 libstdc++-devel = 6.1.1-3.fc24 被 gcc-c++-6.1.1-3.fc24.x86_64 需要
原来gcc-c++的安装还需要依赖其它的软件包。于是我们下载对应版本的C++库,libstdc++和libstdc++-devel。我下载的是libstdc++-6.1.1-3.fc24.x86_64.rpm
和libstdc++-devel-6.1.1-3.fc24.x86_64.rpm
。
现在开始安装libstdc++。
sudo rpm -ivh libstdc++-6.1.1-3.fc24.x86_64.rpm
安装完libstdc++再安装libstdc++-devel。这里需要强制安装,不然会提示如下错误:
libstdc++(x86-64) = 6.1.1-3.fc24 被 libstdc++-devel-6.1.1-3.fc24.x86_64 需要
因为我们已经libstdc++,libstdc++-devel依赖libstdc++,但是rpm可能检测不到我们已经安装的libstdc++,所以只要确定我们已经成功安装libstdc++,就可以强制安装了。
sudo rpm -ivh --force --nodeps libstdc++-devel-6.1.1-3.fc24.x86_64.rpm
安装完libstdc++和libstdc++-devel之后,再强制安装gcc-g++。我们强制忽略gcc-g++依赖的gcc,因为我们不需要。我们需要安装的只是C++开发环境,即编译器g++和C++库。
sudo rpm -ivh --force --nodeps gcc-c++-6.1.1-3.fc24.x86_64.rpm
好了,大功告成,C++的头文件和库会被默认安装到/usr/include和/usr/lib64目录下。关于使用rpm安装软件包指定安装路径,我还没折腾过,大家可以尝试实践一下。
也不知道这种强制安装和忽略gcc会不会带来什么问题,但是目前测试使用C++都没有什么问题。因为我安装的是gcc-c++-6.1.1,g++默认使用C++11和C++14的新特性。所以下面是测试代码。
例子1,测试C++11引入的lambda表达式和初始化列表。
//test.cpp
//Program to test the C++ lambda syntax and initializer lists
#include <iostream>
#include <vector>
using namespace std;
int main(){
// Test lambda
cout << [](int m, int n) { return m + n;} (2,4) << endl;
//Test initializer lists and range based for loop
vector<int> V({1,2,3});
cout << "V =" << endl;
for(auto e : V) {
cout << e << endl;
}
return 0;
}
编译上面的test.cpp文件:g++ test.cpp
然后执行./out,程序输出:
6
V =
1
2
3
例子2,测试C++11引入的正则表达式。
#include <iostream>
#include <regex>
#include <string>
using namespace std;
int main(){
string input;
regex rr("((\\+|-)?[[:digit:]]+)(\\.(([[:digit:]]+)?))?((e|E)((\\+|-)?)[[:digit:]]+)?");
//As long as the input is correct ask for another number
while(true)
{
cout<<"Give me a real number!"<<endl;
cin>>input;
if(!cin) break;
//Exit when the user inputs q
if(input=="q")
break;
if(regex_match(input,rr))
cout<<"float"<<endl;
else
{
cout<<"Invalid input"<<endl;
}
}
}
使用g++编译通过。
本文很多观点也都是参考网上的资源,再加上自己的理解提出来的,难免出错和产生无解,有任何疑问,观点或者有权威的参考资料也请大家能够不吝留言交流!
[1]GNU.百度百科 [2]Compiling GCC 6 on OS X [3] CentOS离线安装gcc4.8.2 [4]RHEL5.4 x86_64 GCC 4.1.2 升级到4.7.0版过程(含安装MPFR、GMP、MPC过程) [5]解决RPM包依赖及强制安装RPM包的方法