一、gcc源碼安裝步驟
1.按網上方式下載了gmp mpfr mpc庫指定版本並安裝
安裝mpfr過程遇到如下問題:
error while loading shared libraries: libgmp.so.10
表示找不到XXX庫,通過find找到庫所有的目錄,添加到環境變量
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/
export LD_LIBRARY_PATH
2.下載 gcc-4.9.2 並安裝
2.1 解壓后進入解壓目錄,執行如下命令生成Makefile文件
./configure --prefix=/usr/gcc-4.9.2 --enable-threads=posix --disable-checking --disable-multilib --enable-languages=c,c++
上面的--prefix=/usr/gcc-4.9.2 表示你要將gcc安裝到gcc-4.9.2的目錄下,其它的選項可以自行去查閱configure了解
2.2 生成Makefile后,執行make -j4編譯
make的過程當中遇到錯誤。網上找了資料說是內存不足free -m,通過增加swap文件分區,問題解決(期間還是出現過一次錯誤,和增加swap分區前的錯誤一樣,我查看了一下內存,發現swap分區還是有很多剩余。所以不管它,接着make -j4,竟然莫名的好了)。
2.3 make完之后,執行make install安裝
二、多個版本編譯器之間的切換方法
安裝好之后,我們通過gcc -v查看gcc版本,發現還是4.4.7的版本。為了執行編譯命令的時候,系統使用4.9.2版本進行編譯。需要將系統默認使用的gcc,從4.4.7版本切換到4.9.2版本,切換方法如下
當linux終端在接收到 gcc/g++ 命令時,shell就會到系統默認的/usr/bin目錄下去找這兩個執行程序(執行shell 命令,實際上是通過shell去調用一個可執行程序的,並且會為每個可執行程序產生一個新進程)。
所以,只需要我們將/usr/bin下的gcc和g++兩個4.4.7的可執行程序,通過軟鏈接,重定向到我們新安裝的4.9.2版本的可執行程序上就可以了。上面我們通過--prefix選項指定了gcc-4.9.2的安裝目錄為/usr/gcc-4.9.2(如果忘記了上面選項設置的路徑,可以通過find來找一下,這個比較簡單,此處不多說),具體操作如下:
cd /usr/bin
mv {gcc,g++} gcc-4.4.7 //先將舊版本的gcc備份起來,以免新版本出錯無法使用,備份是一個好習慣
ln -s /usr/gcc-4.9.2/bin/gcc /usr/bin/gcc
ln -s /usr/gcc-4.9.2/bin/g++ /usr/bin/g++
此時,我們再通過gcc -v查看gcc版本,已經是我們新安裝的gcc-4.9.2版本了。
安裝過程挺久挺煩人的,終於大功告成,聰明的你先happy一下吧。
gcc多個版本之間的切換,都可以使用這個方法,在/usr/bin目錄下建立一個軟鏈接指向你想要使用的版本(除了系統默認的gcc版本,因為系統默認的gcc版本,目錄結構的組織是/usr/bin/gcc這種形式的,它依賴的一些庫在/usr/lib /usr/lib64當中,所以它必須得在/usr/bin目錄下,所以通過軟鏈接來使用系統默認的版本,編譯鏈接的時候可能會出現一些找不到xxx庫的錯誤!)。
通過以上的處理,去建立一個簡單的程序,我們就可以使用新版本gcc進行編譯了,也可以學習c++11了,但是還有一個非常重要的設置。那就是,通過以上設置,在引用一些特定庫的時候,編譯時還是會存在鏈接報錯的情況。比如我,使用了stl中的list,報了如下錯誤。
gcc -g .obj/boostthreadexample.o .obj/charBuffer.o .obj/mysqlprogram.o .obj/structureinit.o .obj/xdbc.o -L/alidata/server/mysql-5.6.15/lib -lmysqlclient -L../common/lib -lxdbc -lbase -lboost_thread -o test
../common/lib/libxdbc.a(connpool.o): In function `std::list<xConnection*, std::allocator<xConnection*> >::_M_insert(std::_List_iterator<xConnection*>, xConnection* const&)':
/usr/gcc/include/c++/4.9.2/bits/stl_list.h:1681: undefined reference to `std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'
collect2: error: ld returned 1 exit status
make: *** [MAINTARGET] Error
錯誤提示找不到`std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)這個符號,原因是:gcc-4.9.2版本編譯鏈接的時候,還是鏈接到/usr/lib目錄下的舊的庫(gcc-4.4.7所依賴的庫的路徑,而這個庫或許做了改動,添加了內容,並且gcc-4.9.2需要使用到這些新內容,在舊的庫找不到新增的符號,是很正常的),導致出現找不到符號的錯誤。我們在編譯的時候遇到這類型錯誤,都可以嘗試考慮一下是否是這個原因。在這里,解決這個問題,有兩個方法。
1、找到這個符號所在的庫,在編譯的時候明確使用它,這種方案有兩個缺點,我們要找到符號所在的庫文件不容易,特別是一些不常見的符號;二是,以后還可能會遇到另外的符號找不到的,又需要去找庫,在編譯的時候指定。
2、仔細想想,既然gcc-4.9.2使用到了這個符號,那么它在安裝的時候,是不是會連帶着將這個新的庫也安裝了呢,非常有可能,趕緊去嘗試一把,將gcc-4.9.2的lib目錄,添加到LD_LIBRARY_PATH環境變量,順便說下LD_LIBRARY_PATH環境變量的作用:編譯器查找庫的順序,是先到LD_LIBRARY_PATH環境變量指定的目錄下去找,找不到之后再到系統默認目錄(通過PATH環境變量指定)去找,也就是說,即使我們在系統默認的目錄下和我們通過LD_LIBRARY_PATH指定的目錄下,存在同名的庫,鏈接的時候是使用LD_LIBRARY_PATH指定目錄下的庫而非系統默認目錄的庫,想要了解更多編譯器查詢庫的順序,可以自行去百度。
此處使用第二種方法,操作如下
在 .bash_profile文件(設置環境變量的文件,CentOS版的linux發布,其它版本的發布,名字或許不太一樣)中加入以下內容,注意將gcc-4.9.2替換成你自己安裝gcc-4.9.2版本的目錄。
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/gcc-4.9.2/lib:/usr/gcc-4.9.2/lib64
export LD_LIBRARY_PATH
這個方法通常可以用來解決編譯時庫的兼容性問題
保存並重啟終端,make,編譯成功。