1. 程式人生 > >CentOS6上編譯安裝gcc8.1版本全過程記錄(包括排坑與常見錯誤解決)

CentOS6上編譯安裝gcc8.1版本全過程記錄(包括排坑與常見錯誤解決)

之前發現開發機上安裝的gcc版本太舊了,連C++11新特性都不支援,於是決定對其進行升級。本文詳細記錄了在CentOS 6上升級gcc的整個過程,特別是其中遇到的坑和解決辦法。

安裝依賴項

先把依賴項裝好

sudo yum install glibc-devel bison flex texinfo build-essential

在安裝的過程中就會發現翻車了:

$ ll
relocation error: /usr/lib64/libc.so.6: symbol _dl_starting_up, version GLIBC_PRIVATE not defined in file ld-linux-x86-64
.so.2 with link time reference

這時會發現幾乎所有常見命令都無法執行了——因為他們都依賴C庫,而現在C庫處於gg狀態。解決方案也很簡單,兩條指令就能搞定。想比於已經啟動不了的ln,sln真是雪中送炭啊!

LD_PRELOAD="/lib64/libc-2.12.so"
sudo sln /lib64/libc-2.12.so /lib64/libc.so.6

下載原始碼

wget http://ftp.gnu.org/gnu/gcc/gcc-8.1.0/gcc-8.1.0.tar.xz
tar -xf ./gcc-8.1.0.tar.xz
cd ./contrib/
./download_prerequisites
cd
..

如果目標機網路不好,則需要下載gcc原始碼到本地,並且將./contrib/download_prerequisites中需要的4個依賴庫原始碼下載好,然後手動上傳、解壓並設定連結。

tar -xf ./isl-0.18.tar.bz2 
tar -xf ./mpc-1.0.3.tar.gz 
tar -xf ./mpfr-3.1.4.tar.bz2 
tar -xf ./gmp-6.1.0.tar.bz2 
ln -sv ./gmp-6.1.0 ./gmp
ln -sv ./mpc-1.0.3 ./mpc
ln -sv ./mpfr-3.1.4 ./mpfr
ln -sv ./isl-0.18 ./isl

編譯

mkdir gcc-build; cd
$_ ../configure -enable-checking=release -enable-languages=c,c++ -disable-multilib

配置完成之後就可以開始編譯了,這裡依據目標機配置選定make後的引數。

make -j8

編譯完後進行安裝

sudo make install

至此已將gcc8.1安裝到了/usr/local/bin下。

軟連結

先檢視當前gcc、g++的路徑:

which gcc
which g++

發現在/usr/bin下。於是先進行備份:

cd /usr/bin
sudo mv gcc gcc.old
sudo mv g++ g++.old
sudo mv gcov gcov.old
sudo mv gccmakedep gccmakedep.old

重要部分備份之後,就可以進行刪除操作了

sudo rm c++ gcc-ar gcov x86_64-pc-linux-gnu-c++ x86_64-pc-linux-gnu-gcc-ar cpp gcc-nm gcov-dump x86_64-pc-linux-gnu-g++ x86_64-pc-linux-gnu-gcc-nm g++ gcc-ranlib gcov-tool x86_64-pc-linux-gnu-gcc x86_64-pc-linux-gnu-gcc-ranlib gcc gcore x86_64-pc-linux-gnu-gcc-8.1.0

下面連結到新編譯的gcc上:

cd /usr/local/bin
sudo ln -s $(pwd)/c++ /usr/bin/c++
sudo ln -s $(pwd)/gcc-ar /usr/bin/gcc-ar
sudo ln -s $(pwd)/gcov /usr/bin/gcov
sudo ln -s $(pwd)/x86_64-pc-linux-gnu-c++ /usr/bin/x86_64-pc-linux-gnu-c++
sudo ln -s $(pwd)/x86_64-pc-linux-gnu-gcc-ar /usr/bin/x86_64-pc-linux-gnu-gcc-ar
sudo ln -s $(pwd)/cpp /usr/bin/cpp
sudo ln -s $(pwd)/gcc-nm /usr/bin/gcc-nm
sudo ln -s $(pwd)/gcov-dump /usr/bin/gcov-dump
sudo ln -s $(pwd)/x86_64-pc-linux-gnu-g++ /usr/bin/x86_64-pc-linux-gnu-g++
sudo ln -s $(pwd)/x86_64-pc-linux-gnu-gcc-nm /usr/bin/x86_64-pc-linux-gnu-gcc-nm
sudo ln -s $(pwd)/g++ /usr/bin/g++
sudo ln -s $(pwd)/gcc-ranlib /usr/bin/gcc-ranlib
sudo ln -s $(pwd)/gcov-tool /usr/bin/gcov-tool
sudo ln -s $(pwd)/x86_64-pc-linux-gnu-gcc /usr/bin/x86_64-pc-linux-gnu-gcc
sudo ln -s $(pwd)/x86_64-pc-linux-gnu-gcc-ranlib /usr/bin/x86_64-pc-linux-gnu-gcc-ranlib
sudo ln -s $(pwd)/gcc /usr/bin/gcc
sudo ln -s $(pwd)/gcore /usr/bin/gcore
sudo ln -s $(pwd)/x86_64-pc-linux-gnu-gcc-8.1.0 /usr/bin/x86_64-pc-linux-gnu-gcc-8.1.0

最後別忘了將C庫更新:

strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX
cd /usr/local/lib64
strings libstdc++.so.6.0.25 | grep GLIBCXX
cd /usr/lib64
rm -r ./libstdc++.so.6
ln -s /usr/local/lib64/libstdc++.so.6.0.25 libstdc++.so.6

升級後常見問題

1.C庫版本不匹配問題

安裝後,如果不進行最後一步,可能會報類似於“/usr/lib64/libstdc++.so.6: version ‘GLIBCXX_3.4.19’ not found”的錯誤,這就是忘了進行上述最後一步造成的。如果遇到了,更新一下C庫就好了。

2. 編譯時錯誤:字串格式非法

之前能編譯通過的專案,現在編譯時會報錯:

unable to find string literal operator 'operator""fmt' with 'const char [15]'

這是由於C++11語法規定,當字串跟變數連線的時候,必須在變數前後增加一個空格才行。

"[%s][%s:%d]: "fmt"\n"          // 在C++11語法下非法
"[%s][%s:%d]: "  fmt  "\n"      // 修改後合法

3. 編譯時警告:無法將字串常量轉為char*

即“warning: ISO C++ forbids converting a string constant to ‘char*’”。這個很好解決,加一個型別強制轉換就行了:

string strSome = "test";
string strSome = (char *)"test";

4. 連結時錯誤:千奇百怪的字串報錯問題

類似於“undefined reference to `google::protobuf::internal::WireFormatLite::ReadBytes(google::protobuf::io::CodedInputStream*, std::__cxx11::basic_string

5. ldconfig報錯

$ ldconfig
ldconfig: Can't unlink /usr/lib64/libstdc++.so.6
ldconfig: /usr/local/lib64/libstdc++.so.6.0.25-gdb.py is not an ELF file - it has the wrong magic bytes at the start.

一個py檔案怎麼可能符合elf格式呢?解決方案也很簡單粗暴,直接將這個檔案刪除,然後再重新ldconfig即可。