###### tags: `Linux-command`
# Install glibc in centos 7 in manually
> 如果嫌麻煩可以直接看[Take Away](https://hackmd.io/EolJ3dfmQe-ILc6h1VGD5g#Take-Away)
## 前言
想必大家都有嘗試著從github下載別人編好的release binary的經驗。
但是往往別人使用的glibc的版本都比自己的電腦擁有的glibc版本還要高。
這時候就會看到以下惱人的訊息。
``` linux
./bytehound/bytehound: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by ./bytehound/bytehound)
./bytehound/bytehound: /lib64/libm.so.6: version `GLIBC_2.29' not found (required by ./bytehound/bytehound)
./bytehound/bytehound: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by ./bytehound/bytehound)
./bytehound/bytehound: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by ./bytehound/bytehound)
./bytehound/bytehound: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by ./bytehound/bytehound)
```
這時候該怎麼辦呢,當然是更新我們的glibc呀!
但是,使用公司的VM又沒有更新底層的權力,這時候就要學會怎麼在local端安裝了!
## glibc installation
首先,先進入glibc下載用的ftp server。
https://ftp.gnu.org/gnu/glibc/
這次我們使用glibc 2.30為例子
https://ftp.gnu.org/gnu/glibc/glibc-2.30.tar.gz
一開始我是參考這篇文章來安裝 [Centos 7 升级 Glibc-2.28](https://cloud.tencent.com/developer/article/2021784),中途我把`--with-headers=/usr/include --with-binutils=/usr/bin`這兩個flag拿掉,因為我不想使用/usr提供的東西,並且加上--disable-werror,來忽略一些不必要的warning。而以下就是完整的指令
``` linux
wget https://ftp.gnu.org/gnu/glibc/glibc-2.30.tar.gz
tar zxvf glibc-2.30.tar.gz
mkdir build && mkdir release
cd build
../glibc-2.30/configure --disable-profile --enable-add-ons --prefix=$(readlink -f ../release) --disable-werror
make -j && make install
```
執行完以後,release的資料夾內就會有所有的東西了。
## 開始DEB....UG
> 為了方便撰寫,以下出現的\<RELEASE\>都替換成上一段的release資料夾
如果上述完成後就結束的話,那就太簡單了我根本不用寫這篇文來記錄我debug過程。
第一,我想要一勞永逸的直接使用glibc,所以我直接把glibc的路徑設到LD_LIBRARY_PATH上面。
`export LD_LIBRARY_PATH=<RELEASE>/lib:${LD_LIBRARY_PATH}`
然後就...崩! 我的prompt怎麼不見了???? ls一下好了...??????
怎麼**segmentation fault**了。
查了一下,我太廢了也找不到解答(如果有人知道的話請跟我說QQ),但是有依稀看到一些stackoverflow的解答是說,glibc太底層了,不要直接把path設過去,可能會使得機器跑不起來。
既然都有人這樣說了,那我不做了。我只在需要高版本glibc的binary去使用新版的ld就好
所以有了以下的指令
``` linux
<RELEASE>/lib/ld-linux-x86-64.so.2 /bin/ls
# Oops, there is a error when loading shared library
/bin/ls: error while loading shared libraries: libselinux.so.1: cannot open shared object file: No such file or directory
```
居然找不到libselinux.so.1,我們用ldd來看看他原本在哪裡。
``` linux
ldd /bin/ls
...
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007ffff7bb4000)
...
```
奇怪,明明是在/lib64這麼顯眼的地方為什麼會找不到呢。在一陣亂google後發現ld-linux-x86-64.so.2有一個flag可以設定library-path
``` linux
<RELEASE>/lib/ld-linux-x86-64.so.2 --library-path /lib64 /bin/ls
```
這個指令貌似可以了。但是當我測試回我想使用的binary時又出問題了。
``` linux
<RELEASE>/lib/ld-linux-x86-64.so.2 --library-path /lib64 ./bytehound
./bytehound: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by ./bytehound)
./bytehound: /lib64/libm.so.6: version `GLIBC_2.29' not found (required by ./bytehound)
./bytehound: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by ./bytehound)
./bytehound: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by ./bytehound)
./bytehound: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by ./bytehound)
```
怎麼又不行了呢???????
這時我猜測使用這個flag後,PATH可能會被重製,所以我嘗試把glibc2.30的lib加進去library-path內
```
<RELEASE>/lib/ld-linux-x86-64.so.2 --library-path <RELEASE>/lib:/lib64 ./bytehound
```
Oh! yes! 這次可以了,我看到了出口的曙光了。
But,人生就是有這個But。正當我開開心心的想用bytehound去替我們公司的產品做memory profiler時又出事了。
``` linux
export MEMORY_PROFILER=warn
LD_PRELOAD=<bytehound installation>/libbytehound.so <RELEASE>/lib/ld-linux-x86-64.so.2 --library-path <RELEASE>/lib:/lib64 <executable>
# Oops
error while loading shared libraries: libstdc++: cannot open shared object file: No such file or directory
```
原來是我們公司產品有link到自己編譯的libstdc++,而library-path flag沒有找到的緣故。
那這簡單,就跟上面的方法一樣,把path加進去。
但此時會發現根本沒完沒了,後來我嘗試把現有的LD_LIBRARY_PATH直接加進中間會發生甚麼事情。
```linux
export MEMORY_PROFILER=warn
LD_PRELOAD=<bytehound installation>/libbytehound.so <RELEASE>/lib/ld-linux-x86-64.so.2 --library-path <RELEASE>/lib:${LD_LIBRARY_PATH}:/lib64 <executable>
```
這樣就可以了! 以後我們就可以用類似的方法來執行這些高版本glibc的執行檔了。
下面是我之後簡單包裝的wrapper
``` bash
#!/bin/bash
library_path="<RELEASE>/lib:${LD_LIBRARY_PATH}:/lib64"
<RELEASE>/lib/ld-linux-x86-64.so.2 --library-path ${library_path} $@
```
## Take Away
* installtion
* ``` linux
wget https://ftp.gnu.org/gnu/glibc/glibc-2.30.tar.gz
tar zxvf glibc-2.30.tar.gz
mkdir build && mkdir release
cd build
../glibc-2.30/configure --disable-profile --enable-add-ons -- prefix=$(readlink -f ../release) --disable-werror
make -j && make install
```
* wrap the library_path
* ``` bash
#!/bin/bash
library_path="<RELEASE>/lib:${LD_LIBRARY_PATH}:/lib64"
<RELEASE>/lib/ld-linux-x86-64.so.2 --library-path ${library_path} $@
```