1. 程式人生 > >importerror: /usr/lib64/libstdc++.so.6: version `glibcxx_3.4.17' not found 問題解決

importerror: /usr/lib64/libstdc++.so.6: version `glibcxx_3.4.17' not found 問題解決

在使用tensorflow的時候,經常會遇到這個:

 /usr/lib64/libstdc++.so.6: version `glibcxx_3.4.17' not found 、ImportError: /lib64/libc.so.6: version `GLIBC_2.16' not found ...

歸根結底這類問題:由於Linux核心不支援,gcc版本太低!!!!

檢視系統、gcc版本:centos6.4 64位、gcc4.4.7

cat /etc/redhat-release
CentOS release 6.4 (Final)

uname -a
。。。。。.el6.x86_64

$ g++ --version
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

GCC 4.4.7 不支援 C++11,在升級gcc的時候使用yum是無效的,只能下載原始碼、編譯。

$ yum update gcc
Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
Setting up Update Process
No Packages marked for Update

1、下載、解壓:

cd /usr/local
wget ftp://gcc.gnu.org/pub/gcc/releases/gcc-4.8.5/gcc-4.8.5.tar.bz2

tar jxvf gcc-4.8.5.tar.bz2 -C /usr/local/src

在這裡我們直接通過官方下載gcc-4.8.5.tar.bz2(83 MB)。當然,你也可以下載gcc-4.8.5.tar.gz(106 MB),不過該壓縮檔案要大出不少。官方的下載地址為:ftp://gcc.gnu.org/pub/gcc/releases/gcc-4.8.5/ 直接在瀏覽器中開啟即可。如果需要按照其他的版本,開啟上一級目錄 ftp://gcc.gnu.org/pub/gcc/releases/,選擇對應版本下載即可。

2、編譯前準備工作:

想要安裝gcc 4.8及以上版本,你需要先安裝C標準庫和標頭檔案,以及舊版本的c++編譯器。如果你的計算機中沒有這些,請執行以下命令(當然你也可以使用apt-get等其它方式進行安裝,如果已經安裝則無需再次安裝):

#安裝C和C++的靜態庫
yum install -y glibc-static libstdc++-static
#安裝舊版本的gcc、c++編譯器
yum install gcc gcc-c++

3、下載一些必要依賴

#轉到gcc源程式根目錄
cd /usr/local/src/gcc-4.8.5
#下載一些必備的依賴程式
./contrib/download_prerequisites

安裝gcc需要下載諸如gmp、mpfr、mpc等依賴檔案,執行download_prerequisites將會自動下載這些軟體並解壓到當前目錄(檔案不大,總共只有幾MB,請耐心等待下載)。如果網路不OK時,可開啟 ./contrib/download_prerequisites 檔案按照檔案中的內容下載對應版本的依賴程式,並解壓到/usr/local/src/gcc-4.8.5目錄,同時建立對應的軟連線,gcc-4.8.5的download_prerequisites如下:

MPFR=mpfr-2.4.2
GMP=gmp-4.3.2
MPC=mpc-0.8.1

wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$MPFR.tar.bz2 || exit 1
tar xjf $MPFR.tar.bz2 || exit 1
ln -sf $MPFR mpfr || exit 1

wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$GMP.tar.bz2 || exit 1
tar xjf $GMP.tar.bz2  || exit 1
ln -sf $GMP gmp || exit 1

wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$MPC.tar.gz || exit 1
tar xzf $MPC.tar.gz || exit 1
ln -sf $MPC mpc || exit 1

rm $MPFR.tar.bz2 $GMP.tar.bz2 $MPC.tar.gz || exit 1

所以需要下載三個依賴程式:mpfr、gmp和mpc,在 ftp://gcc.gnu.org/pub/gcc/infrastructure/ 目錄下依次找到對應的三個檔案,並下載後放在/usr/local/src/gcc-4.8.5目錄下,每個依賴庫的目錄使用ln -sf做成軟連線即可。

4、編譯安裝gcc:

接著,就可以對gcc進行編譯安裝了。在此之前,我們先建立一個目錄 mkdir /usr/local/build/gcc-4.8.5(你也可以自行指定其他目錄)用於存放編譯後的程式檔案。然後我們依次執行如下命令:

#跳轉到編譯後的程式檔案存放目錄
cd /usr/local/build/gcc-4.8.5
#呼叫gcc源程式的configure(後面的引數選項可根據需要自行修改),用於配置gcc
/usr/local/src/gcc-4.8.5/configure --enable-checking=release --enable-languages=c,c++ --disable-multilib
#編譯gcc源程式
make
#安裝gcc
make install

其中執行make命令這一過程耗費的時間可能非常多,筆者這裡耗費了2個多鐘頭才編譯完成。執行完上述命令後,我們的gcc就已經安裝成功了。

GCC 和G++均安裝在/usr/local/bin/ 和 /usr/local/lib 目錄下,如果需要自己指定安裝目錄,在configure後面指定引數 --prefix=/your/path 即可。

5、解決GLIBC版本未更新問題:

編譯或者執行時,會出現GLIBC版本找不到的問題,如下提示:

/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found
/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found

主要是因為升級時,生成的動態庫沒有替換老版本gcc的動態庫導致的,將gcc最新版本的動態庫替換系統中老版本的動態庫即可解決。執行以下命令檢查動態庫:

# strings /usr/lib64/libstdc++.so.6 | grep GLIBC

GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBC_2.2.5
GLIBC_2.3
GLIBC_2.4
GLIBC_2.3.2
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH

從以上輸出可以看出,gcc的動態庫還是舊版本的。說明出現這些問題,是因為升級gcc時,生成的動態庫沒有替換老版本gcc的動態庫。按道理說安裝的時候會自動更新動態庫,我們可以在根目錄手動搜尋一下:

# find / -name libstdc++.so.6*  
/usr/lib/libstdc++.so.6.0.13
/usr/lib/libstdc++.so.6
/usr/local/lib64/libstdc++.so.6.0.19-gdb.py
/usr/local/lib64/libstdc++.so.6
/usr/local/lib64/libstdc++.so.6.0.19
/usr/local/build/gcc-4.8.5/x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6
/usr/local/build/gcc-4.8.5/x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.19
/usr/local/build/gcc-4.8.5/stage1-x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6
/usr/local/build/gcc-4.8.5/stage1-x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.19
/usr/local/build/gcc-4.8.5/prev-x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6
/usr/local/build/gcc-4.8.5/prev-x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.19
/usr/lib64/libstdc++.so.6.0.13
/usr/lib64/libstdc++.so.6

我們發現,gcc安裝時把libstdc++.so.6.0.19 安裝到了/usr/local/lib64下,但並沒有改變/usr/lib64/libstdc++.so.6的連結指向。那麼我們將/usr/local/lib64/libstdc++.so.6.0.19手動拷貝到/usr/lib64/,並更新libstdc++.so.6軟連線(也可以直接指向/usr/local/lib64/libstdc++.so.6.0.19,不用拷貝, 看各自的檔案管理習慣),其中/usr/local/build/gcc-4.8.5/目錄下的庫檔案為都是編譯輸出檔案,stage1-x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.19為gcc新版本編譯最終生成的lib庫檔案,和/usr/local/lib64/libstdc++.so.6.0.19是一模一樣的。更新lib庫的操作命令如下:

cp /usr/local/lib64/libstdc++.so.6.0.19 /usr/lib64 
rm -rf /usr/lib64/libstdc++.so.6
ln -s /usr/lib64/libstdc++.so.6.0.19 /usr/lib64/libstdc++.so.6

再次檢查動態庫:

strings /usr/lib64/libstdc++.so.6 | grep GLIBC
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBC_2.3
GLIBC_2.2.5
GLIBC_2.3.2
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH

庫更新完畢。我們已經支援到了GLIBCXX_3.4.14-19,此時再進行編譯,GLIBCXX的問題是沒有了。

參考:https://www.cnblogs.com/yczcc/p/7874903.html