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即可。