欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2023-12-31 18:49:40
...

1  下载源文件

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

 

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

2 编译安装

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

#创建编译目录

mkdir gcc-9.2.0-build

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

 

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++

 

 

相关标签: gcc

上一篇:

下一篇: