升级ubuntu上的编译工具链详细方法

       前几天使用c++11以上的新语法编译程序,发现在ubuntu服务器编译都有异常提示,分析是ubuntu自带的编译工具及库太老的,不支持新的语法。针对找个问题,这两天将服务器的gcc/g++工具链升级到了11版本(之前是5.4),同时更新了glibc库到3.4.29.完成这些工作后,后续的编译可以直接使用最新的语法,对后续升级ubuntu的工具链和库有较大意义。

       以下是完成步骤,阅读过程中,有几点需要注意:

1:本文手动升级,如果能用简单方法(添加ppa软件源),会更加快捷,但手动升级对完成升级流程及可能问题有更深入理解。

2:升级过程的顺序比较重要,随意修改会带来较大调试量,得不偿失

3:现在软件包都需要configure,之后生成makefile,之后make,configure的参数需要理解。

4:更新glibc的方法。

1:问题描述

前几天测试一个对比目录生成日期的代码,代码如下:

  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5. #include   
  6. #include   
  7. #include   
  8. #include   
  9.   
  10. using std::vector;  
  11. using std::string;  
  12. int main(int argc, char *argv[])  
  13. {  
  14.     struct stat dirstat;  
  15.     int result;  
  16.     DIR *d;  
  17.     struct dirent *de;  
  18.     vectordirVec;  
  19.     struct timespec tstmtime;  
  20.   
  21.     if (argc < 2)  
  22.     {  
  23.         printf("param-num:%d \r\n", argc);  
  24.         return -1;  
  25.     }  
  26.       
  27.     d = opendir(argv[1]);  
  28.     if (d == NULL)  
  29.     {  
  30.         printf("opendir: %s failed ! \r\n", argv[1]);  
  31.         return -1;  
  32.     }  
  33.     while((de = readdir(d)) != NULL)  
  34.     {  
  35.         string str(de->d_name);  
  36.         dirVec.push_back(str);  
  37.     }  
  38.       
  39.     for(auto& dir : dirVec)  
  40.     {  
  41.         lstat(dir.c_str(), &dirstat);  
  42.         if ((dirstat.st_mode & S_IFMT) == S_IFDIR)  //目录文件  
  43.         {  
  44.             printf("dir:%s, at-time:%ld, mt-time:%ld, ct-time:%ld \r\n",   
  45.                     dir.c_str(), dirstat.st_atime, dirstat.st_mtime, dirstat.st_ctime);  
  46.             string strTmp1 = ".";  
  47.             string strTmp2 = "..";        
  48.             if (dir.compare(".") || dir.compare(".."))    
  49.             {  
  50.                 printf("Don't touch current dir:%s \r\n", dir.c_str());  
  51.                 continue;  
  52.             }  
  53.               
  54.             clock_gettime(CLOCK_REALTIME, &tstmtime);  
  55.             time_t ttSec = tstmtime.tv_sec;  
  56.             printf("Current time:%ld \r\n", ttSec);  
  57.             if (ttSec > dirstat.st_ctime + 300)  
  58.             {  
  59.                 printf("dir:%s, created over 100 \r\n", dir.c_str());  
  60.             }  
  61.         }  
  62.     }  
  63.     closedir(d);  
  64. }  
  65. 直接编译的时候,出现错误

升级ubuntu上的编译工具链详细方法_第1张图片

问题分析:

此时很多语法并不支持,需要升级到新版本的gcc/g++才能满足要求.

目前老的工具链不支持新的C++语法,查看gcc编译器版本:

升级ubuntu上的编译工具链详细方法_第2张图片

 需要升级到一个新版本,以下就详细讲解如何升级ubuntu的gcc/g++工具链。

2:简单方法及失败分析

参照网络的方式,主要的流程包括:

sudo apt-get update

sudo apt-get upgrade

以上就是使用/etc/apt/source.list中指定的网站来更新当前的软件,

之后增加一个第三方软件来源:

sudo add-apt-repository ppa:ubuntu-toolchain-r/test

此处会等待很长时间,也可能会通过,通过之后,就会将:

ppa:ubuntu-toolchain-r/test添加到你的程序源地址,这个地址在:/etc/apt/sources.list.d

之后更新软件源:sudo apt-get update

之后安装最新gcc:sudo apt-get install gcc-11

但实际安装的时候,会提示无法下载,,如下:

 或者认证等问题

升级ubuntu上的编译工具链详细方法_第3张图片

 按照网上处理方法,将source.list从阿里服务器修改为中科大的,如下source.list

升级ubuntu上的编译工具链详细方法_第4张图片

 效果也是一样的,最后没办法,只有自己下载编译了,以下就是完整过程

3.手动下载软件包

3.1 先下载gcc的软件包

先下载gcc包:gcc-11.2.0.tar.gz

通过清华的镜像网站:

mkdir sys-upd //创建一个目录

cd sys-upd  

wget https://mirrors/tinghua/gnu/gcc-11.2.0/gcc-11.2.0.tar.gz

下载完后,解压

tar -zxvf gcc-11.2.0.tar.gz

3.2 执行依赖文件下载

./contrib/download_prerequisites

提示文件下载,但下载失败了,实际下载的只有4K吧,实际文件都是1~2M的,

查看download_prerequisites文件,实际需要下载如下4个文件

gmp='gmp-6.1.0.tar.bz2'

mpfr='mpfr-3.1.6.tar.bz2'

mpc='mpc-1.0.3.tar.gz'

isl='isl-0.18.tar.bz2'

文件下载来源为:base_url='http://gcc.gnu.org/pub/gcc/infrastructure/'

手动wget下载这个几个包试试,按照download_prerequisites上的下载地址:

wget http://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.1.0.tar.bz2

实际获取的文件确实就只有4K,显然不正确,使用浏览器查看和下载就1.9M,这个可能是公司网络的限制吧。

3.3 手动下载依赖文件

既然不能自动下载依赖文件,那就找个可用的镜像网站下载,如清华镜像网站

base_url='https://mirrors.tuna.tsinghua.edu.cn/gnu/'

实际浏览器可以打开查看的,不过挺尴尬的是:清华的gnu下面多了一级目录,和gcc.gnu.org/pub/gcc/infrastructure/ 下直接文件不同

如下图就是gnu官网的

升级ubuntu上的编译工具链详细方法_第5张图片

 下图是清华镜像网站的:

升级ubuntu上的编译工具链详细方法_第6张图片

实际的压缩文件包在各自的目录中,不好直接修改download_prerequisites文件,那就手动下载吧。

以下操作网上也有描述:

3.3.1:下载、编译、安装gmp-6.1.0.tar.bz2

  1. wget https://mirrors.tuna.tsinghua.edu.cn/gnu/gmp/gmp-6.1.0.tar.bz2  
  2. tar -vxf gmp-6.1.0.tar.bz2  
  3. cd gmp-6.1.0/  
  4. ./configure --prefix=/usr/local/gmp-6.1.0  
  5. make  
  6. sudo make install  
  7. cd..

3.3.2:下载、编译、安装mpfr-3.1.6.tar.bz2

  1. wget https://mirrors.tuna.tsinghua.edu.cn/gnu/mpfr/mpfr-3.1.6.tar.bz2  
  2. tar -xvf mpfr-3.1.6.tar.bz2  
  3. cd mpfr-3.1.6/  
  4. ./configure --prefix=/usr/local/mpfr-3.1.6 --with-gmp=/usr/local/gmp-6.1.0  
  5. Make  
  6. sudo make install  
  7. cd ..  

3.3.3:下载、编译、安装mpc-1.0.3.tar.gz

  1. wget https://mirrors.tuna.tsinghua.edu.cn/gnu/mpc/mpc-1.0.3.tar.gz  
  2. tar -xvf mpc-1.0.3.tar.gz  
  3. cd mpc-1.0.3/  
  4. ./configure --prefix=/usr/local/mpc-1.0.3 --with-gmp=/usr/local/gmp-6.1.0 --with-mpfr=/usr/local/mpfr-3.1.6  
  5. Make  
  6. sudo make install  
  7. cd ..  

特别注意:以上1.2.3步是固定的,因为mpfr需要依赖--with-gmp,而mpc需要依赖--with-gmpwith-mpfr,如果顺序不对,make就会提示出错。

4.安装

4.1 :设置环境变量

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/mpc-1.0.3/lib:/usr/local/gmp-6.1.0/lib:/usr/local/mpfr-3.1.6/lib  

4.2:生成gcc编译makefile

./configure --prefix=/usr/local/gcc-11.2 -enable-threads=posix -disable-checking -disable-multilib -enable-languages=c,c++ -with-gmp=/usr/local/gmp-6.1.0 -with-mpfr=/usr/local/mpfr-3.1.6 -with-mpc=/usr/local/mpc-1.0.3  

4.3:编译、安装

Make –j4        //此过程比较漫长,我编译了将近2小时(电脑比较菜)  

Sudo make install  

5 配置

5.1:查看版本及配置

还是老的, 直接到目录下看看:

升级ubuntu上的编译工具链详细方法_第7张图片

 已经是更新到11.2.0了,那是环境变量不正确

5.2 修改下环境变量

export PATH=/usr/local/gcc-11.2/bin:$PATH  

gcc –v  

升级ubuntu上的编译工具链详细方法_第8张图片

 此时就已经是最新的了。

编译最初的测试代码测试下:

 No error, no warning!!!

最后,为了保证每次登陆及每个用户登陆都使用最新的PATH,需要修改下环境变量

sudo vim /etc/profile  

//最后增加一行  

export PATH=/usr/local/gcc-11.2/bin:$PATH  

6. 运行配置

6.1 直接执行程序

kongcb@tcu-pc:~/testcode$ kongcb@tcu-pc:~/testcode$ ./testdir ./  

./testdir: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by ./testdir)  

kongcb@tcu-pc:~/testcode$  

无法执行,问题分析就是:

调用的高版本的gcc,生成的动态库没有替换老版本gcc的动态库导致的,需要找到新版的gcc库更新。

6.2更新系统gcc库

查找库:

kongcb@tcu-pc:~/sys-upd/gcc/prev-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs$ locate libstdc++.so.6.0.29                                          

/home/clou-tcu/kongcb/sys-upd/gcc/prev-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.29  

查找库支持的libc版本

kongcb@tcu-pc:~/sys-upd/gcc/prev-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs$ strings libstdc++.so.6.0.29 | grep GLIBCXX_3.4.29  

GLIBCXX_3.4.29  

GLIBCXX_3.4.29  

将该文件迁移过去

sudo rm /usr/lib/x86_64-linux-gnu/libstdc++.so.6  

sudo ln /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.29 /usr/lib/x86_64-linux-gnu/libstdc++.so.6 -s  

再运行程序,结果正确,如下:

  1. 升级ubuntu上的编译工具链详细方法_第9张图片

你可能感兴趣的:(系统操作,linux应用,linux,系统操作,ubuntu,服务器,linux)