GCC 9.2 compiler installation method and C++17 standard test example in Ubuntu 16 system

Posted by gijew on Sun, 14 Jun 2020 09:25:44 +0200

1. Download the source file

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

 

2 compile and install

#decompression
tar zxvf gcc-9.2.0.tar.gz

#Create compilation directory

mkdir gcc-9.2.0-build

As shown in the figure

 

3 download dependency package

cd /home/gcc/gcc-9.2.0-build

../gcc-9.2.0/configure

Will report an error

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.

terms of settlement

cd /home/gcc/gcc-9.2.0

vi contrib/download_prerequisites


Put the

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

Replace with:

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

Replace the server address that does not exist with the mirror server address. Next, execute the following command to download and decompress the dependency package automatically:

bash contrib/download_prerequisites
Here's a hint. It's a success
All prerequisites downloaded successfully.

 

cd /home/gcc/gcc-9.2.0-build

../gcc-9.2.0/configure --disable-multilib   #Option disable multilib disable 32-bit

make

Waiting for a long time....

make install

Specifies that the latest version of GCC compiler is used locally

Use the update alternatives command to add the latest compiler. Note: gcc is the default program for compiling C programs, and g + + is the default program for compiling C programs.

# Update alternatives -- install < link > < name > < Path > < priority >
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

Use the following command to query the currently installed version of GCC compiler:

# Query the existing GCC compiler of this machine
sudo update-alternatives --query gcc
# Query the existing G + + compiler
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

Select the GCC compiler version to use by default:

 

# Interactive configuration GCC compiler
sudo update-alternatives --config gcc
# Interactive configuration G + + compiler
sudo update-alternatives --config g++

You can use the following command to query the current gcc and g + + versions:

# Query gcc version
gcc --version
# Query g++ version
g++ --version

C++ 17 standard program test

#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.

 

Use G++9.2.0 to build a multithreaded program. When running the program, it looks like ". / main: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.22 'not found (required by. / main) "error

#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)

Add / usr / lib / x86_ 64 Linux GNU / libstdc + +. So. 6 modify the suffix backup, and copy / usr/local/lib64/libstdc++.so.6 to the local. The command is as follows:

cd /usr/lib/x86_64-linux-gnu
# Back up the original version
sudo mv libstdc++.so.6 libstdc++.so.6.bk
# Copy new version
sudo cp /usr/local/lib64/libstdc++.so.6 ./
# Update shared library cache
sudo ldconfig

Then, verify that the new "libstdc++.so.6" file contains ` glibcxx_ Version 3.4.22 '(this step may not be performed).

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

Recompile build

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! 

Unable to downgrade GCC compiler version

Although the latest version of GCC compiler is very comfortable to use, some old code may still need the old version of GCC compiler to compile. At this time, we naturally think of using

sudo update-alternatives --config gcc

The command configures the version, but it is found that no matter how I set the options, the gcc-v command always outputs the following information:

Use built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-pc-linux-gnu/9.2.0/lto-wrapper
 Target: x86_64-pc-linux-gnu
 Configuration is:.. / gcc-9.2.0/configure -- Disable multilib
 Thread model: posix
 gcc version 7.2.0 (GCC)

That is, you cannot downgrade the GCC version.
The reason for this problem is that we set the priority of GCC7.3.0 too high. Due to the high priority and new version of GCC 7.3.0, no matter how we manually select the GCC version, the system will still match the newer version of GCC program.
The solution is to set the priority of the old version of GCC program higher. The specific operations are as follows:

# 1. Delete the old GCC configuration item with low priority
sudo update-alternatives --remove gcc /usr/bin/gcc-5
sudo update-alternatives --remove g++ /usr/bin/g++-5
# 2. Reinstall old GCC configuration items with higher priority
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. At this time, you can change the current GCC version
sudo update-alternatives --config gcc
sudo update-alternatives --config g++

 

 

Topics: sudo Linux ftp glibc