Ubuntu 16系统中GCC 9.2编译器安装方法及C++17标准测试示例

1  下载源文件

   http://mirror.linux-ia64.org/gnu/gcc/releases/gcc-9.2.0/

 

2 编译安装

#解压
tar zxvf gcc-9.2.0.tar.gz

#创建编译目录

mkdir gcc-9.2.0-build

  如图所示

 

3 下载依赖包

cd /home/gcc/gcc-9.2.0-build

../gcc-9.2.0/configure

会报错

configure: error: Building GCC requires GMP 4.2+, MPFR 2.4.0+ and MPC 0.8.0+.
Try the --with-gmp, --with-mpfr and/or --with-mpc options to specify
their locations.  Source code for these libraries can be found at
their respective hosting sites as well as at
ftp://gcc.gnu.org/pub/gcc/infrastructure/.  See also
http://gcc.gnu.org/install/prerequisites.html for additional info.  If
you obtained GMP, MPFR and/or MPC from a vendor distribution package,
make sure that you have installed both the libraries and the header
files.  They may be located in separate packages.

解决办法

cd /home/gcc/gcc-9.2.0

vi contrib/download_prerequisites


将该文件里的

base_url='ftp://gcc.gnu.org/pub/gcc/infrastructure/'

替换为:

base_url='http://mirror.linux-ia64.org/gnu/gcc/infrastructure/',

即将不存在的服务器地址替换为镜像服务器地址。接下来,执行如下命令自动下载并解压依赖包:

bash contrib/download_prerequisites
有提示这个,证明成功
All prerequisites downloaded successfully.

 

cd /home/gcc/gcc-9.2.0-build

../gcc-9.2.0/configure --disable-multilib   #选项disable-multilib 禁用32位

make

等了好久好久。。。。

make install

指定本机使用最新版本GCC编译器

使用update-alternatives命令配置增加最新版本编译器,注意:gcc是编译C程序的默认程序,g++是编译C++程序的默认程序。

# update-alternatives --install <链接> <名称> <路径> <优先级>
sudo update-alternatives --install /usr/bin/gcc gcc /usr/local/bin/gcc 50
sudo update-alternatives --install /usr/bin/g++ g++ /usr/local/bin/g++ 50

使用下述命令查询当前已经安装的GCC编译器版本:

# 查询本机已有GCC编译器情况
sudo update-alternatives --query gcc
# 查询本机已有G++编译器情况
sudo update-alternatives --query g++
Name: gcc
Link: /usr/bin/gcc
Status: auto
Best: /usr/local/bin/gcc
Value: /usr/local/bin/gcc

Alternative: /usr/bin/gcc-5
Priority: 20

Alternative: /usr/local/bin/gcc
Priority: 50
Name: g++
Link: /usr/bin/g++
Status: auto
Best: /usr/local/bin/g++
Value: /usr/local/bin/g++

Alternative: /usr/bin/g++-5
Priority: 20

Alternative: /usr/local/bin/g++
Priority: 50

选择默认使用的GCC编译器版本:

 

# 交互配置GCC编译器
sudo update-alternatives --config gcc
# 交互配置G++编译器
sudo update-alternatives --config g++

可以使用如下命令查询当前的gccg++版本:

# 查询gcc版本
gcc --version
# 查询g++版本
g++ --version

C++ 17标准程序测试

#include <iostream>
#include <tuple>
#include <map>
#include <stdexcept>

bool divide_remainder(int dividend, int divisor, int &fraction, int &remainder)
{
    if (divisor == 0)
    {
        return false;
    }
    fraction = dividend / divisor;
    remainder = dividend % divisor;
    return true;
}

std::pair<int, int> divide_remainder(int dividend, int divisor)
{
    if (divisor == 0)
    {
        throw std::runtime_error{"Attempt to divide by 0"};
    }
    return {dividend / divisor, dividend % divisor};
}

int main()
{
    { // old school way
        int fraction, remainder;
        const bool success{divide_remainder(16, 3, fraction, remainder)};
        if (success)
        {
            std::cout << "16 / 3 is " << fraction << " with a remainder of " << remainder << "\n";
        }
    }

    { // C++11 way
        const auto result(divide_remainder(16, 3));
        std::cout << "16 / 3 is " << result.first << " with a remainder of " << result.second << "\n";
    }

    { // C++11, ignoring fraction part of result
        int remainder;
        std::tie(std::ignore, remainder) = divide_remainder(16, 5);
        std::cout << "16 % 5 is " << remainder << "\n";
    }

    { // C++17, use structured bindings
        auto[fraction, remainder] = divide_remainder(16, 3);
        std::cout << "16 / 3 is " << fraction << " with a remainder of " << remainder << "\n";
    }

    { // C++17, decompose a tuple into individual vars
        std::tuple<int, float, long> tup{1, 2.0, 3};
        auto[a, b, c] = tup;
        std::cout << a << ", " << b << ", " << c << "\n";
    }

    { // C++17, use structured binding in for-loop

        std::map<std::string, size_t> animal_population{
            {"humans", 7000000000},
            {"chickens", 17863376000},
            {"camels", 24246291},
            {"sheep", 1086881528}
            /* … */
        };

        for (const auto & [ species, count ] : animal_population)
        {
            std::cout << "There are " << count << " " << species << " on this planet.\n";
        }
    }
}

g++ -g -Wall -std=c++17 *.cpp -o test

./test
16 / 3 is 5 with a remainder of 1
16 / 3 is 5 with a remainder of 1
16 % 5 is 1
16 / 3 is 5 with a remainder of 1
1, 2, 3
There are 24246291 camels on this planet.
There are 17863376000 chickens on this planet.
There are 7000000000 humans on this planet.
There are 1086881528 sheep on this planet.

 

使用G++9.2.0构建多线程程序,运行程序时出现类似“./main: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.22’ not found (required by ./main)”的错误

#include <iostream>
#include <queue>
#include <tuple>
#include <condition_variable>
#include <thread>

using namespace std;
using namespace chrono_literals;

queue<size_t> q;
mutex mut;
condition_variable cv;
bool finished = false;

void producer(size_t items) {
    for (size_t i = 0; i < items; ++i) {
        this_thread::sleep_for(100ms);
        {
            lock_guard<mutex> lk(mut);
            q.push(i);
        }
        cv.notify_all();
    }

    {
        lock_guard<mutex> lk(mut);
        finished = true;
    }
    cv.notify_all();
}

void comsumer() {
    while (!finished) {
        unique_lock<mutex> lk(mut);
        cv.wait(lk, []() {
            return !q.empty() || finished;
        });

        while (!q.empty()) {
            cout << "Got " << q.front() << " from queue. " << endl;
            q.pop();
        }
    }
}

int main() {
    thread t1(producer, 10);
    thread t2(comsumer);

    t1.join();
    t2.join();

    cout << "Finished! " << endl;
    return 0;
}

 

g++ -g -Wall -std=c++17 -pthread *.cpp -o main

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

/usr/lib/x86_64-linux-gnu/libstdc++.so.6修改后缀名备份,并将/usr/local/lib64/libstdc++.so.6复制到本地,命令如下:

cd /usr/lib/x86_64-linux-gnu
# 备份原有版本
sudo mv libstdc++.so.6 libstdc++.so.6.bk
# 复制新版本
sudo cp /usr/local/lib64/libstdc++.so.6 ./
# 更新共享库缓存
sudo ldconfig

然后,确认检查新的“libstdc++.so.6”文件已包含`GLIBCXX_3.4.22’版本(该步骤可不执行)。

strings ./libstdc++.so.6 | grep GLIBC

重新编译生成

g++ -g -Wall -std=c++17 -pthread *.cpp -o main

./main

Got 0 from queue. 
Got 1 from queue. 
Got 2 from queue. 
Got 3 from queue. 
Got 4 from queue. 
Got 5 from queue. 
Got 6 from queue. 
Got 7 from queue. 
Got 8 from queue. 
Got 9 from queue. 
Finished! 

无法将GCC编译器版本降级

最新版本的GCC编译器虽然用起来很舒服,但一些旧代码可能还是需要老版本的GCC编译器才能编译,这时我们自然想到使用

sudo update-alternatives --config gcc

命令去配置版本,但经过实践发现,无论我怎么设置选项,gcc -v命令总是输出如下信息:

使用内建 specs。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-pc-linux-gnu/9.2.0/lto-wrapper
目标:x86_64-pc-linux-gnu
配置为:../gcc-9.2.0/configure --disable-multilib
线程模型:posix
gcc 版本 7.2.0 (GCC)

也就是说,无法将GCC版本降级。
该问题产生的原因是,我们将GCC7.3.0的优先级设置得太高了。由于GCC7.3.0的优先级高、版本也新,无论我们怎么手动选择GCC版本,系统仍然会匹配版本较新的GCC程序。
解决方法是:将老版本的GCC程序优先级设置得更高。具体操作如下:

# 1.删除原有低优先级的老GCC配置项
sudo update-alternatives --remove gcc /usr/bin/gcc-5
sudo update-alternatives --remove g++ /usr/bin/g++-5
# 2.以更高的优先级重新安装老GCC配置项
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 70
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 70
# 3.这时就可以更改当前使用的GCC版本了
sudo update-alternatives --config gcc
sudo update-alternatives --config g++

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值