您现在的位置是:首页 > 正文

Linux升级GCC清晰简明教程

2024-02-29 10:56:59阅读 3
前言:

 

这次我在Ubuntu 12.04 LTS 64位版上更新gcc,发现了原来的一些问题,这次没有什么时间上的压力,我比较认真地去查阅了官方文档,也参考了一些网上的帖子,对整个升级过程在依赖包的安装不同Linux流派32和64位下的区别和共同点有了更深的认识。

现总结如下:

PS:不标注出处的转载是可耻的。

(如果你很忙的话,可以只把里面的shell代码复制出来执行)

 

基本过程:
这里对整个流程做一个概要性的介绍,让大家在做每一件事情的时候做到心中有数。
 
1,安装依赖库和工具
根据官方文档,如果只是为了编译安装而不是去修改gcc,那么所需要的库和工具并不是很多。
需要强调的有两点:
1)需要一个c++编译器,也就是说如果只有gcc而无g++,那么是无法完成这次编译的;
2)在64位系统上如果想要编译出32位的程序的话,需要额外安装相应的库(默认开启)。
 
2,配置(configure)
配置我们编译出的gcc所支持的语言,目标环境(是否为交叉编译器),依赖库路径(一定条件下可省略,下详),编译结果安装到哪里……配置程序会根据这些信息生产Makefile文件,供下一步使用。
 
3,编译(make)
根据configure生成的Makefile编译出我们的gcc和相应的lib如libstdc++等。
 
流程:
请大家多多查阅官方文档:http://gcc.gnu.org/install/
一,安装依赖库与工具

工具:

支持c++98的编译器(g++),make,perl,解压工具(tar、gzip等),Binutils(部分情况下需要)等。
这里一般不需要太担心,因为现在的linux系统在安装完成后,这里面的大部分工具就已经就位了,唯一需要注意的就是c/c++环境。
如果确定本机已经安装了gcc和g++那么可以跳过这一部分。
 
Unbutu下可以使用:

1. apt-get install build-essential
来方便地搞定,而且它还安装了一些其他必须的库如glibc(Ubuntu下叫libc)。
其他一些Linux平台没有build-essential这个包,稍微麻烦一点。
因为安装g++和gcc,必然会安装libstdc++和glibc,所以建议通过:

1. apt-get install gcc g++ make libc6-dev

的方式来安装,以避免一些恶心的问题,还可以确保相应工具的安装。
 

库:

根据官方文档,如果只是安装不修改的话只需要5个依赖第三方库。
这个5个库分2类,一类(gmp,mpc,mpfr)是可以在gcc编译过程中自动编译的(先自行下载了源码并正确放置),另一类是需要独立安装的(isl,cloog)。

操作:

1,检查它们是否已经安装了:
如果要检查XXX库是否安装,使用:

1. locate libXXX
来查找,如果查找到libXXX.so文件,那么就说明这个库已经安装了。

2,安装(如果第一步发现某个库已经装了自然就不用再装啦):
对于gmp,mpc,mpfr三个库,可以在gcc的解压根目录下运行

1. ./contrib/download_prerequisites

来下载并解压,并创建符号连接。(如果下载缓慢,可以修改脚本中的下载地址到其他gnu镜像,注意修改版本号,根据官网的说明更高的版本不会引发其他问题)

 

根据gcc的编译规则:如果在gcc的根目录下有gmp,mpc,mpfr这几个目录,那么在make gcc的时候,它们会 自动make, 不需要手动安装。
 
对于isl和cloog这个两个库,可以自己编译(编译时请详细阅读官方文档),但是建议直接从源上面下载。因为cloog依赖了gmp和isl,这就是说如果你要编译
例如:

1. apt-get intall libisl-dev libcloog-isl3

在具体环境下可能需要修改库的名字,这一点可以通过在输入完libisl或libcloog后按两下Tab键来查看,后同。

 
3,安装其他库:
如果希望在64位系统下也能编译出32位的程序,那么还需要32位的运行库,而这些库在64位系统下默认是不会安装的。
Ubuntu下有简单的方法,可以使用:

1. apt-get install gcc-multilib g++-multilib

Fedora下可以使用:
 

1. apt-get install glibc-devel.i686 libstdc++-devel.i686

Ubuntu下也可以借鉴这个模式,修改包名安装相应的包。

二,配置(configure)

1,建立编译目录

在gcc解压根目录下创建一个用于存放编译时生产的.o文件的目录。

1. mkdir build
2. cd build

2,配置

在刚刚建立的临时目录里面,调用根目录下下的configure,并输入其他参数,这里我只介绍常用的几个。
--prefix
用于配置make install之后将生产的可执行文件、库文件放到哪个根目录下,例如--prefix=/usr,那么生产的gcc和g++会放在/usr/bin下,生产的lib会放在/usr/lib下。如果你希望 替换掉原来的gcc和lib,那么使用通过“which gcc”命令找到的根路径。默认情况下--prefix为/usr/local。可以通过update-alternatives来配置拥有多个gcc时默认使用哪一个(后面介绍)。
--program-prefix
--program-suffix
给编译出来的gcc加上前缀和后缀。例如--program-prefix=my --program-suffix=4.8.1,那么生成的gcc的名字会是:“my-gcc-4.8.1”
--disable-multilib
使编译出来的gcc成为本地编译器(native compiler),即生产的目标代码只保证能在本机默认运行。
对于64位的系统,这个选项是 默认关闭的,即默认情况下得到的gcc可以通过编译时的选项(-m32)来决定生成64位还是32位的目标代码。所以需要先安装gcc-multilib(glibc-devel.i686)。对于32位系统,默认是开启的,即不去生成64的程序。
--enable-languages
这个就是说明需要让编译出来的gcc支持的语言。和大多数人一样,对于gcc我只用它的c和c++,其他语言没有配置,所以不保证本文档对于编译其他语言的情况也是正确的。
 

--with-gmp
--with-mpfr
--with-mpc
--with-isl
--with-cloog
--with-gmp-include
--with-gmp-lib
 

如果已经安装了上述某个库,且不再标准的库搜索路径(自动安装一般不存在这个问题),需要手动指定相应路径。
--with-XXX=YYY等价于--with-XXX-include=YYY/include 和 --with-XXX-lib=YYY/lib
 
假设系统为64位的,当前gcc安装在/usr/bin目录下:
例如(作为本地编译器,共存两个gcc,支持c和c++):

1. ../configure --prefix=/usr/local --disable-multilib --enable-languages=c,c++
或(可以生成32位可执行文件,覆盖原来的gcc,支持c和c++,自行编译了gmp到/usr/gmp-5.1.3/下):

1. ../configure --prefix=/usr --enable-languages=c,c++ --with-gmp=/usr/gmp-5.1.3

3,检查

即使存在一些问题,confiure也是可以成功生成Makefile文件的,但是这些问题会导致后面的make过程出错。因而很多人(包括我)忽略了这一步,导致了一些令人头痛的问题。
打开与Makefile文件同时生成的config.log文件,搜索里面的“error”,正常情况下只会搜到一些条件信息里面的error如-Werror,和获取信息时使用“gcc -V”但gcc不支持-V之类的错误,这些无关大局。但如果出现了 include某个文件不存在,那就需要注意了。例如#include<isl/xxx.h>出错,就说明没有安装libisl-dev包。
三,编译(make)
到了这一步,就没什么那么麻烦了:

1. sudo make -j4

对于更好的机器-j后面的数字可以更大一些。

没有问题后,执行:

1. sudo make install

install的路径是在configure的时候配置的。

 

需要说明的是:
1,gcc 不支持make unintall,覆盖请谨慎。
2,这一步请使用root权限进行,否则必悲剧。

四,后继工作

如果希望共存两个版本的gcc,使用的时候自然可以通过输入完整路径来致命调用哪个gcc,但是这样比较复杂。

建议通过update-alternatives 来让系统知道当我们只输入gcc的时候,是希望调用哪一个(关于update-alternatives的详细用法请百度):

例如我的gcc的路径为/usr/local/bin/gcc,我给它一个100的优先级:


1. sudo update-alternatives --install /usr/bin/gcc gcc /usr/local/bin/gcc 100

然后通过
 

1. sudo update-alternatives --config gcc

来查看两个gcc中系统选中了哪个(auto情况下是选中优先级高的),如果auto选中的不是我们要的,可以增加优先级或者手工制定默认的。

 

 

在其他Linux版本:

在升级gcc个过程中,主要区别就在于包的名字和包管理器的不同。

 

Ubuntu系(Debian)的包名和RedHat系(CentOS、Fedora)的在命名规则上不太一样。前缀洗好加版本号,开发版缩写为“dev”,用“-”连接架构;而后者的开发版缩写为”devel“,用”.“连接架构。

例如在安装32位的glibc的时候所使用的报名:

On Ubuntu: libc6-dev-i386.
On Red Hat distros: glibc-devel.i686
On CentOS 5.8: glibc-devel.i386
On CentOS 6.3: glibc-devel.i686

其次Ubuntu系有很多整合了的包,例如g++-multilib,build-essential等,而ReadHat系没有。

原载于http://blog.csdn.net/yanxiangtianji

网站文章