安装GCC-8.3.0及其依赖

目录

目录 1

1. 前言 1

2. 安装日期 1

3. GCC国内镜像下载地址 2

4. GCC的依赖库 2

4.1. gmp库 2

4.2. mpfr库 2

4.3. mpc库 2

4.4. m4编译工具 3

4.5. 安装源代码包 3

5. 编译安装gmp 3

6. 编译安装mpfr 4

7. 编译安装mpc 4

8. 设置LD_LIBRARY_PATH 4

9. 编译安装gcc 4

10. 编译安装m4 6

附1:cmake支持 6

附2:debug STL 6

附3:体验C++14 7

附4:体验C++17 9

附5:体验C++20 11

附6:C++标准 12

附7:C++标准当前状态 13

附8:其它 15

 

1. 前言

为体验C++17和C++20特性,需安装更新版本的GCC编译器。GCC官网为:https://gcc.gnu.org/,从这里可以下载最新版本的GCC。

C++由Bjarne Stroustrup(被誉为C++之父)于1979年在新泽西州美利山贝尔实验室开始设计开发的,最初命名为带类的C,后来在1983年更名为C++。

2. 安装日期

2019/4/27,截至该日期最新版本为GCC-8.3.0,但在本月未或下月初即将发布GCC-9.1.0(已于2019-05-03发布),本文同样适用于GCC-9.1.0的编译安装。

3. GCC国内镜像下载地址

下载速度不一,请选择速度最快的(9.1.0的URL类似):

1) http://mirrors.nju.edu.cn/gnu/gcc/gcc-8.3.0/

2) http://mirrors.ustc.edu.cn/gnu/gcc/gcc-8.3.0/

3) https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-8.3.0/

4. GCC的依赖库

编译之前需先安装好GCC的依赖库:gmpmpfrmpc。编译还依赖m4等编译工具,如果没有,则在执行configue时会报相应的错误,这时需要先安装好这些编译工具。

4.1. gmp库

GMP为“GNU MP Bignum Library”的缩写,是一个GNU开源数学运算库。本文选择的是最新版本gmp-6.1.2,国内镜像下载地址:

1) https://mirrors.tuna.tsinghua.edu.cn/gnu/gmp/

2) http://mirrors.nju.edu.cn/gnu/gmp/

3) http://mirrors.ustc.edu.cn/gnu/gmp/

4.2. mpfr库

mpfr是一个GNU开源大数运算库,它依赖gmp。本文选择的是最新版本mpfr-4.0.2,国内镜像下载地址:

1) https://mirrors.tuna.tsinghua.edu.cn/gnu/mpfr/

2) http://mirrors.nju.edu.cn/gnu/mpfr/

3) http://mirrors.ustc.edu.cn/gnu/mpfr/

4.3. mpc库

mpc是GNU的开源复杂数字算法,它依赖gmp和mpfr。本文选择的是最新版本mpc-1.1.0,国内镜像下载地址:

1) https://mirrors.tuna.tsinghua.edu.cn/gnu/mpc/

2) http://mirrors.nju.edu.cn/gnu/mpc/

3) http://mirrors.ustc.edu.cn/gnu/mpc/

4.4. m4编译工具

本文选择的是最新版本m4-1.4.16,下载地址:

1) https://mirrors.tuna.tsinghua.edu.cn/gnu/m4/

2) http://mirrors.nju.edu.cn/gnu/m4/

3) http://mirrors.ustc.edu.cn/gnu/m4/

 

如果使用“--prefix”指定了安装目录,则在编译gmp等之前还需先设置好环境变量PATH,以便configure时能找到m4。

4.5. 安装源代码包

涉及到的所有安装源代码包:

gcc-8.3.0.tar.gz

mpfr-4.0.2.tar.gz

gmp-6.1.2.tar.xz

mpc-1.0.3.tar.gz

 

GCC的依赖库间还互有依赖:mpfr依赖gmp、mpc依赖gmp和mpfr,所以GCC的编译安装顺序为:

1) m4(如果需要)

2) gmp

3) mpfr

4) mpc

5) GCC

 

为了不污染已有的编译和运行环境,将GCC及依赖库均安装到/usr/local目录,并且最好以root用户完成下述所有操作。

5. 编译安装gmp

执行configure生成Makefile时,需要用到m4,一般路径为/usr/bin/m4,如果没有则需要先安装,否则报错“no usable m4”错误,手工安装m4从“https://www.gnu.org/software/m4/”下载。

具体安装步骤如下:

xz -d gmp-6.1.2.tar.xz

tar xf gmp-6.1.2.tar

cd gmp-6.1.2

./configure --prefix=/usr/local/gmp-6.1.2

make

make install

ln -s /usr/local/gmp-6.1.2 /usr/local/gmp

6. 编译安装mpfr

详细安装步骤如下:

tar xzf  mpfr-4.0.2.tar.gz

cd mpfr-4.0.2

./configure --prefix=/usr/local/mpfr-4.0.2 --with-gmp=/usr/local/gmp

make

make install

ln -s /usr/local/mpfr-4.0.2 /usr/local/mpfr

7. 编译安装mpc

tar xzf  mpc-1.1.0.tar.gz

cd mpc-1.1.0

./configure --prefix=/usr/local/mpc-1.1.0 --with-gmp=/usr/local/gmp --with-mpfr=/usr/local/mpfr

make

make install

ln -s /usr/local/mpc-1.1.0 /usr/local/mpc

8. 设置LD_LIBRARY_PATH

在编译GCC之前,如果不设置LD_LIBRARY_PATH(如果编译gmp时没有指定“--prefix”时安装,一般不用再显示设置),则可能编译时报“error while loading shared libraries: libmpfr.so.6: cannot open shared object file: No such file or directory”等错误。

export LD_LIBRARY_PATH=/usr/local/gmp/lib:/usr/local/mpfr/lib:/usr/local/mpc/lib:$LD_LIBRARY_PATH

9. 编译安装gcc

在执行make编译GCC时,有些费时,请耐心等待。在一台Intel Xeon 2.30GHz的48核128GB内存机器上花费228分钟(将近4个小时,同台机器编译9.1.0花费190分钟),编译GCC-8.3.0的GCC版本为4.8.5(64位)。

tar xzf gcc-8.3.0.tar.gz

cd gcc-8.3.0

./configure --prefix=/usr/local/gcc-8.3.0 --with-mpfr=/usr/local/mpfr --with-gmp=/usr/local/gmp --with-mpc=/usr/local/mpc

date;time make;date

make install

ln -s /usr/local/gcc-8.3.0 /usr/local/gcc

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

export LD_LIBRARY_PATH=/usr/local/gcc/lib64:/usr/local/gmp/lib:/usr/local/mpfr/lib:/usr/local/mpc/lib:$LD_LIBRARY_PATH

export MANPATH=/usr/local/gcc/share/man:$MANPATH

gcc --version

 

在执行configure时,如果遇到错误“I suspect your system does not have 32-bit development libraries (libc and headers). If you have them, rerun configure with --enable-multilib. If you do not have them, and want to build a 64-bit-only compiler, rerun configure with --disable-multilib”,表示系统不支持32位程序,这样在执行configure时需为它支持参数“--disable-multilib”,如:

./configure --prefix=/usr/local/gcc-8.3.0 --with-gmp=/usr/local/gmp --with-mpfr=/usr/local/mpfr --with-mpc=/usr/local/mpc --disable-multilib

 

如果make时遇到错误“internal compiler error”,可能是因为内存不足,请换台内存更大的机器,或者更换GCC版本试试。

如果遇到错误“C compiler cannot create executables”、“error while loading shared libraries: libmpfr.so.6: cannot open shared object file: No such file or directory”或“cannot compute suffix of object files”,可尝试设置LD_LIBRARY_PATH后再试试:

export LD_LIBRARY_PATH=/usr/local/gmp/lib:/usr/local/mpfr/lib:/usr/local/mpc/lib:$LD_LIBRARY_PATH

 

make成功结束时的输出:

make[8]: 离开目录“/data/GCC/gcc-8.3.0/x86_64-pc-linux-gnu/32/libatomic”

make[7]: 离开目录“/data/GCC/gcc-8.3.0/x86_64-pc-linux-gnu/32/libatomic”

make[6]: 离开目录“/data/GCC/gcc-8.3.0/x86_64-pc-linux-gnu/32/libatomic”

make[5]: 离开目录“/data/GCC/gcc-8.3.0/x86_64-pc-linux-gnu/libatomic”

make[4]: 离开目录“/data/GCC/gcc-8.3.0/x86_64-pc-linux-gnu/libatomic”

make[3]: 离开目录“/data/GCC/gcc-8.3.0/x86_64-pc-linux-gnu/libatomic”

make[2]: 离开目录“/data/GCC/gcc-8.3.0/x86_64-pc-linux-gnu/libatomic”

make[1]: 离开目录“/data/GCC/gcc-8.3.0

 

在完成上列步骤后,检查新安装的GCC-8.3.0是否可用:

# gcc --version

gcc (GCC) 8.3.0

Copyright © 2018 Free Software Foundation, Inc.

本程序是自由软件;请参看源代码的版权声明。本软件没有任何担保;

包括没有适销性和某一专用目的下的适用性担保。

 

# man gcc|col -b|grep c++17

           c++17

               GNU dialect of -std=c++17.  The name gnu++1z is deprecated.

           This flag is enabled by default for -std=c++17.

           arguments as an argument for a template template parameter with fewer template parameters.  This flag is enabled by default for -std=c++17.

           adopted for C++17.  Enabled by default with -std=c++17.  -fstrong-eval-order=some enables just the ordering of member access and shift

           expressions, and is the default without -std=c++17.

           -Wc++17-compat.

           "register" keyword as storage class specifier has been deprecated in C++11 and removed in C++17.  Enabled by default with -std=c++17.

       -Wc++17-compat (C++ and Objective-C++ only)

 

已经支持C++20标准,但因为标准还未正式发布,所以正式发布后大概率发生变化:

# man gcc|col -b|grep c++2a

           c++2a

               GNU dialect of -std=c++2a.  Support is highly experimental, and will almost certainly change in incompatible ways in future releases (支持是高度实验性的,并且在将来的版本中几乎肯定会以不兼容的方式发生变化).

10. 编译安装m4

只有m4不可用或版本过低时才需安装m4(一般路径为/usr/bin/m4),如果configure时不指定prefix,则可省去export和ln两步:

tar xzf m4-1.4.16

cd m4-1.4.16

./configure --prefix=/usr/local/m4-1.4.16

make

make install

ln -s /usr/local/m4-1.4.16 /usr/local/m4

export PATH=/usr/local/m4/bin:$PATH

附1:cmake支持

在使用cmake前,需设置好下列所环境变量,否则cmake仍将使用默认目录下的gcc和g++,在CMakeFiles.txt文件中设置CMAKE_C_COMPILER和CMAKE_CXX_COMPILER不能解决这个问题。如果在此之前已经执行过cmake,则得先删除CMakeFiles目录和文件CMakeCache.txt,然后再重新执行cmake生成Makefile文件。

export CC=/usr/local/gcc/bin/gcc

export CXX=/usr/local/gcc/bin/g++

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

export LD_LIBRARY_PATH=/usr/local/gcc/lib64:$LD_LIBRARY_PATH

export LD_LIBRARY_PATH=/usr/local/gmp/lib:/usr/local/mpfr/lib:/usr/local/mpc/lib:$LD_LIBRARY_PATH

附2:debug STL

有时需要debug STL中的容器等,正常情况下没法跟踪STL中的代码,只需要加上编译宏“_GLIBCXX_DEBUG”即可开启对STL的debug。注意这个并不是GCC编译器定义的,而是直接在STL源代码中定义的。细心点可发现在STL库头文件目录中有一个debug子目录,以4.8.5为例:

$ ls /usr/include/c++/4.8.5/debug

array    deque         functions.h  map         multiset.h       safe_iterator.tcc        safe_sequence.h        safe_unordered_container.h    set.h          unordered_set

bitset   formatter.h   list         map.h       safe_base.h      safe_local_iterator.h    safe_sequence.tcc      safe_unordered_container.tcc  string         vector

debug.h  forward_list  macros.h     multimap.h  safe_iterator.h  safe_local_iterator.tcc  safe_unordered_base.h  set                           unordered_map

 

查看正常的文件,即可看到“_GLIBCXX_DEBUG”:

vi /usr/include/c++/4.8.5/map

 

#ifdef _GLIBCXX_DEBUG

# include <debug/map>

#endif

 

#ifdef _GLIBCXX_PROFILE

# include <profile/map>

#endif

附3:体验C++14

// C++14

#include <iostream>

 

[[deprecated]]

auto foo1() {

  int m = 2019;

  return m;

}

 

[[deprecated("foo2 is deprecated")]]

auto foo2() {

  int m = 2020;

  return m;

}

 

int main() {

  const auto n1 = foo1();

  const auto n2 = foo2();

  std::cout << "n1: " << n1 << std::endl

            << "n2: " << n2 << std::endl;

  return 0;

}

 

编译运行结果如下:

$g++ -o main *.cpp

main.cpp: In function ‘int main()’:

main.cpp:17:24: warning: ‘auto foo1()’ is deprecated [-Wdeprecated-declarations]

   const auto n1 = foo1();

                        ^

main.cpp:5:6: note: declared here

 auto foo1() {

      ^~~~

main.cpp:18:24: warning: ‘auto foo2()’ is deprecated: foo2 is deprecated [-Wdeprecated-declarations]

   const auto n2 = foo2();

                        ^

main.cpp:11:6: note: declared here

 auto foo2() {

      ^~~~

$main

n1: 2019

n2: 2020

 

如果在C++11上编译,会报语法错误:

main.cpp:5:11: error: 'foo1' function uses 'auto' type specifier without trailing return type

 auto foo1() {

           ^

main.cpp:5:11: note: deduced return type only available with -std=c++14 or -std=gnu++14

main.cpp:11:11: error: 'foo2' function uses 'auto' type specifier without trailing return type

 auto foo2() {

           ^

main.cpp:11:11: note: deduced return type only available with -std=c++14 or -std=gnu++14

main.cpp: In function 'int main()':

main.cpp:17:24: warning: 'auto foo1()' is deprecated [-Wdeprecated-declarations]

   const auto n1 = foo1();

                        ^

main.cpp:5:6: note: declared here

 auto foo1() {

      ^~~~

main.cpp:17:24: warning: 'auto foo1()' is deprecated [-Wdeprecated-declarations]

   const auto n1 = foo1();

                        ^

main.cpp:5:6: note: declared here

 auto foo1() {

      ^~~~

main.cpp:18:24: warning: 'auto foo2()' is deprecated: foo2 is deprecated [-Wdeprecated-declarations]

   const auto n2 = foo2();

                        ^

main.cpp:11:6: note: declared here

 auto foo2() {

      ^~~~

main.cpp:18:24: warning: 'auto foo2()' is deprecated: foo2 is deprecated [-Wdeprecated-declarations]

   const auto n2 = foo2();

                        ^

main.cpp:11:6: note: declared here

 auto foo2() {

      ^~~~

附4:体验C++17

// C++17

#include <iostream>

 

template <auto v>

auto foo() {

  return v;

}

 

int main() {

  std::cout << "foo return: " << foo<2019>() << std::endl;

  for (int i=0; i<10; ++i) {

    if (int m=i%2;0==m)

      std::cout << "i: " << i << std::endl;

  }

  return 0;

}

 

编译运行结果如下:

foo return: 2019

i: 0

i: 2

i: 4

i: 6

i: 8

 

再体验一段来源于http://www.modernescpp.com/index.php/functional-in-c-17-and-c-20的C++17代码:

// foldExpression.cpp

#include <iostream>

 

template<typename... Args>

bool all(Args... args) { return (... && args); }

template<typename... Args>

bool any(Args... args) { return (... || args); }

template<typename... Args>

bool none(Args... args) { return not(... || args); }

 

int main(){ 

  std::cout << std::endl;

  std::cout << std::boolalpha;

  std::cout << "all(true): " << all(true) << std::endl;

  std::cout << "any(true): " << any(true) << std::endl;

  std::cout << "none(true): " << none(true) << std::endl;

  std::cout << std::endl;

  std::cout << "all(true, true, true, false): " << all(true, true, true, false) << std::endl;

  std::cout << "any(true, true, true, false): " << any(true, true, true, false) << std::endl;

  std::cout << "none(true, true, true, false): " << none(true, true, true, false) << std::endl;

  std::cout << std::endl;

  std::cout << "all(false, false, false, false): " << all(false, false, false, false) << std::endl;

  std::cout << "any(false, false, false, false): " << any(false, false, false, false) << std::endl;

  std::cout << "none(false, false, false, false): " << none(false, false, false, false) <<  std::endl;

  std::cout << std::endl;  

}

 

编译运行结果如下:

all(true): true

any(true): true

none(true): false

 

all(true, true, true, false): false

any(true, true, true, false): true

none(true, true, true, false): false

 

all(false, false, false, false): false

any(false, false, false, false): false

none(false, false, false, false): true

附5:体验C++20

1) Concept

源代码来源:https://zh.cppreference.com/w/cpp/language/constraints,GCC-9.1.0上可编译。

// g++ -g -o concept concept.cpp -std=c++17 -fconcepts

#include <iostream>

#include <string>

#include <cstddef>

using namespace std::literals;

 

// 概念 "Hashable" 的声明,"Hashable" 为概念名,概念不能递归及自身,

// 任何对于 T 类型值,表达式 std::hash<T>{}(a) 可编译,

// 而其结果可转换为 std::size_t 的类型 T 满足它

template<typename T>

concept Hashable = requires(T a) {

    { std::hash<T>{}(a) } -> std::size_t;

};

 

struct meow {};

 

template<Hashable T>

void f(T); // 有制约的 C++20 函数模板

 

// 应用同一制约的替用方式:

// template<typename T>

//    requires Hashable<T>

// void f(T); 

// 

// template<typename T>

// void f(T) requires Hashable<T>; 

 

int main() {

  f("abc"s); // OK : std::string 满足 Hashable

//  f(meow{}); // 错误: meow 不满足

}

 

template<Hashable T>

void f(T t) {

    const std::size_t n = std::hash<T>{}(t);

    std::cout << n << std::endl;

}

 

如果将“”打开,编译时报如下错误:

$ g++ -g -o concept concept.cpp -std=c++17 -fconcepts

concept.cpp: 在函数‘int main()’中:

concept.cpp:30:11: 错误:cannot call function ‘void f(T) [with T = meow]’

   30 |   f(meow{}); // 错误: meow 不满足

      |           ^

concept.cpp:18:6: 附注:  constraints not satisfied

   18 | void f(T); // 有制约的 C++20 函数模板

      |      ^

concept.cpp:11:9: 附注:within ‘template<class T> concept const bool Hashable<T> [with T = meow]’

   11 | concept Hashable = requires(T a) {

      |         ^~~~~~~~

concept.cpp:11:9: 附注:    with ‘meow a’

concept.cpp:11:9: 附注:the required expression ‘std::hash<_Tp>{}(a)’ would be ill-formed

附6:C++标准

可浏览https://en.cppreference.com/w/cpp/compiler_support了解各编译器对C++标准的支持详情。C++标准官网:https://isocpp.org/

年份

C++标准

名称

__cplusplus值

重大新特性

1998

ISO/IEC 14882:1998

C++98

199711L

第一个C++标准

2003

ISO/IEC 14882:2003

C++03

199711L

第二个C++标准

2011

ISO/IEC 14882:2011

C++11

201103L

第三个C++标准

1) auto关键字

2) 右值引用

3) nullptr关键字

4) shared_ptr/unique_ptr/weak_ptr

5) long long

6) lambda(类似JS的闭包)

7) decltype

8) constexpr

9) delete/default

10) final/override

11) noexcept

12) std::tuple

13) std::move

14) 变长参数的模板

15) 模板“>>”(两个“>”间不再需空格)

16) 多线程并发支持:thread_local、std::atomic、std::thread等

2014

ISO/IEC 14882:2014

C++14

201402L

第四个C++标准

1) 函数可返回auto(返回值类型推导)

2) 泛型lambda

3) deprecated属性

4) std::optional

5) 二进制常量和数字分隔符

2017

ISO/IEC 14882:2017

C++17

201703L

第五个C++标准

1) 删除三字符词(如“??=”、“??-”等)

2) if/switch语句内可定义和初始化变量

3) std::any/std::variant

4) 内联变量(可在头文件中定义变量)

5) __has_include

6) 并行STL

7) 折叠表达式(fold expression)

8) 构造函数的模板推导(class template deduction)

9) 结构化绑定(structured bindings)

2020

暂未定

C++20

 

第六个C++标准(暂未正式发布):

1) 协程(coroutines,GCC-9.1.0不支持)

2) 模块化(modules,GCC-9.1.0不支持)

3) Concepts(模板的编译错误更好理解,GCC-9.1.0支持,但需打开编译开关“-std=c++17”和“-fconcepts”)

4) Ranges(GCC-9.1.0不支持)

 

截止到9.1.0版本,GCC都不支持module,如需体验module特性,用SVN下载开发分支:svn://gcc.gnu.org/svn/gcc/branches/c++-modules,gzip压缩后约247M。

 

未定

C++23

 

 

 

 

C++26

 

 

附7:C++标准当前状态

注:TS为“Technical Specifications”的缩写,IS为“International Standard”的缩写,TR为“Technical Report”的缩写。

附8:其它

默认情况下GCC下的本地static对象或变量总是线程安全的,副作用是代码段变大,可以通过指定“-fno-threadsafe-statics”阻止默认行为,但牺牲了线程安全性。

Do not emit the extra code to use the routines specified in the C++ ABI for thread-safe initialization of local statics. You can use this option to reduce code size slightly in code that doesn't need to be thread-safe.

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值