# centos7 升级 glibc && gcc
Date: 2020-07-18


### 环境

- cenos7(X86\_64)

为了验证 `mmap()`一些功能需要升级glibc版本， 顺便把gcc一起升级一下

### 升级`gcc`

#### 预安装包

安装过程中需要`makeinfo`, 先安装下`texi2html`, `texinfo`

```C
yum install texi2html texinfo 
```

#### 安装gcc

```C
wget https://ftp.gnu.org/gnu/gcc/gcc-10.1.0/gcc-10.1.0.tar.gz

tar zxvf gcc-10.1.0.tar.gz
cd gcc-10.1.0/
mkdir build
cd build
/configure --enable-languages=c,c++ --disable-multilib
make && make install
```

#### 验证

```C
# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=...
Target: x86_64-pc-linux-gnu
Configured with: ../configure --enable-languages=c,c++ --disable-multilib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.1.0 (GCC)
```

### 升级`glibc`

#### 预安装包

我的机器上是要求安装最新的`make`, 网上有需要升级`ld`, 的下载安装`binutils`就可以了

```C
wget https://ftp.gnu.org/pub/gnu/make/make-4.3.tar.gz
tar zxvf make-4.3.tar.gz
cd make-4.3
mkdir build
./configure
make && make install
cp /usr/bin/make make.backup
ln /usr/local/bin/make /usr/bin/make
```

#### 安装glibc

```C
wget http://ftp.gnu.org/gnu/glibc/glibc-2.31.tar.gz
tar -xvf  glibc-2.31.tar.gz
mkdir glibc-2.31/build
cd glibc-2.31/build
../configure --prefix=/usr --with-headers=/usr/include
 --with-binutils=/usr/bin
make
make install
```

#### 问题 `make install` 报错

```C
/usr/bin/perl scripts/test-installation.pl /tmp/glibc-2.31/build/ 
/usr/bin/ld: cannot find -lnss_test2
...
LD_SO=ld-linux-x86-64.so.2 CC="gcc -B/usr/bin/" /usr/bin/perl
 scripts/test-installation.pl /tmp/glibc-2.31/build/
/usr/bin/ld: /lib/../lib64/libnss_nis.so: undefined reference to
'_nsl_default_nss@GLIBC_PRIVATE'
```

可以从上面脚本信息看到是 `scripts/test-installation.pl` 有报错, 进去看一下, 主目录下的 `Makefile`

```C
    122 ifneq (no,$(PERL))
    123 ifeq (/usr,$(prefix))
    124 ifeq (,$(install_root))
    125         LD_SO=$(ld.so-version) CC="$(CC)" $(PERL) scripts/
    test-installation.pl $(common-objpfx)
    126 endif
    127 endif
    128 endif
    129 endif
    130 endif
```

`123 ifeq (/usr,$(prefix))` 看来是和`configure`配置的`prefix`设置为`/usr`有关

具体的脚本 `scripts/test-installation.pl` 大致流程:

1. 读取共享库版本;
2. 使用这些动态库生成一个文件;
3. 通过ldd检验一下

#### 解决动态库 `nss_test2` 报错

调整一下 增加下面一行不再进行验证

```C
    128         && $name ne "nss_test2"
```

```C
    105 # Read names and versions of all shared libraries that are part of
    106 # glibc
    107 open SOVERSIONS, $soversions
    ...
    111 %versions = ();
    112
    113 while (<SOVERSIONS>) {
    114   next if (/^all-sonames/);
    115   chop;
    116   if (/^lib/) {
    117     ($name, $version)= /^lib(.*)\.so-version=\.(.*)$/;
    118     # Filter out some libraries we don't want to link:
    119     # - nss_ldap since it's not yet available
    120     # - libdb1 since it conflicts with libdb
    121     # - libthread_db since it contains unresolved references
    122     # - it's just a test NSS module
    123     # - We don't provide the libgcc so we don't test it
    124     # - libmvec if it wasn't built
    125     next if ($build_mathvec == 0 && $name eq "mvec");
    126     if ($name ne "nss_ldap" && $name ne "db1"
    127         && $name ne "thread_db"
    128         && $name ne "nss_test2"
    129         && $name ne "nss_test1" && $name ne "libgcc_s") {
    130       $link_libs .= " -l$name";
    131       $versions{$name} = $version;
    132     }
    133   } elsif ($LD_SO ne "") {
    134     ($ld_so_name, $ld_so_version) = split ('\.so\.', $LD_SO);
    135   } else {
    136     if (/^ld\.so/) {
    137       ($ld_so_name, $ld_so_version)= /=(.*)\.so\.(.*)$/;
    138     }
    139   }
    140 }
    ....
```

#### 解决动态库 `undefined reference to '_nsl_default_nss@GLIBC_PRIVATE'`

这个看下`nis/Makefile`

```C
     71 ifeq ($(build-obsolete-nsl),yes)
     72 libnsl-routines += nss-default
```

`configure` 增加 `--enable-obsolete-nsl`

```C
#configure --help
  --enable-obsolete-nsl   build and install the obsolete libnsl 
  library and depending NSS modules
```

按照下面格式重新调整一下，重新编译就可以了

```C
../configure --prefix=/usr --with-headers=/usr/include
 --with-binutils=/usr/bin  --enable-obsolete-nsl
```

### 参考及引用

[How to Compile and Install Latest Version of GCC on CentOS 7](https://jdhao.github.io/2017/09/04/install-gcc-newer-version-on-centos/) [What is makeinfo, and how do I get it?](https://stackoverflow.com/questions/338317/what-is-makeinfo-and-how-do-i-get-it)

