6.17.1. 安裝 GCC
GCC 的文件建議在原始碼目錄之外一個專用的編譯目錄中編譯 GCC:
mkdir -v ../gcc-build
cd ../gcc-build
準備編譯 GCC:
SED=sed
../gcc-4.9.2/configure
--prefix=/usr
--enable-languages=c,c++
--disable-multilib
--disable-bootstrap
--with-system-zlib
注意,對於其它的程式語言,現在還有一些前提條件沒有準備好。可以檢視
BLFS Book 瞭解如何編譯 GCC 支援的所有語言的指令。
新配置選項的含義:
-
SED=sed
-
設定環境變數防止訪問到硬編碼的 /tools/bin/sed 路徑。
-
--with-system-zlib
-
這個選項告訴 GCC 連結系統安裝的 Zlib 庫,而不是它內部自帶的庫。
編譯軟體包:
make
重要
本章節中 GCC 的測試套件至關重要,任何情況下都不能跳過。
GCC 測試套件中一個測試集的會耗盡堆疊空間,因此執行測試之前要增加棧大小:
ulimit -s 32768
測試編譯結果,但不要因為出現錯誤就停下來:
make -k check
要檢視測試套件結果的概要,執行:
../gcc-4.9.2/contrib/test_summary
如果只是檢視概要,可以將輸出通過管道送到 grep -A7 Summ
。
結果可以和 http://www.linuxfromscratch.org/lfs/build-logs/7.7-systemd/
以及 http://gcc.gnu.org/ml/gcc-testresults/ 上的相比較。
一些意料之外的錯誤總是難以避免。GCC 開發者通常意識到了這些問題,但還沒有解決。除非測試結果和上面 URL 中的相差很大,不然就可以安全繼續。
安裝軟體包:
make install
一些軟體包希望 GCC 安裝在 /lib
目錄。為了支援那些軟體包,可以建立一個符號連結:
ln -sv ../usr/bin/cpp /lib
譯者注:如果還在 gcc-build 目錄,這裡應該是 ln -sv ../../usr/bin/cpp /lib 。
很多軟體包用命令 cc 呼叫 C 編譯器。為了滿足這些軟體包,建立一個符號連結:
ln -sv gcc /usr/bin/cc
增加一個相容符號連結啟用編譯程式時進行連結時間優化(Link Time Optimization,LTO):
install -v -dm755 /usr/lib/bfd-plugins
ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/4.9.2/liblto_plugin.so /usr/lib/bfd-plugins/
現在我們最終的工具鏈已經準備就緒了,再一次確認編譯和連結都能像預期那樣正常工作很重要。我們通過做和前面章節做過的相同的完整性檢查做到這點:
echo `main(){}` > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep `: /lib`
這應該沒有錯誤,最後一個命令的輸出應該是(允許平臺相關的動態連結器名字有差異):
[Requesting program interpreter: /lib/ld-linux.so.2]
現在確認我們設定了正確的啟動檔案:
grep -o `/usr/lib.*/crt[1in].*succeeded` dummy.log
最後一個命令的輸出應該是:
/usr/lib/gcc/i686-pc-linux-gnu/4.9.2/../../../crt1.o succeeded
/usr/lib/gcc/i686-pc-linux-gnu/4.9.2/../../../crti.o succeeded
/usr/lib/gcc/i686-pc-linux-gnu/4.9.2/../../../crtn.o succeeded
取決於你機器的架構,上面的結果可能有稍微不同,差異通常是 /usr/lib/gcc
後目錄的名稱。如果你的是 64 位系統,你也許能看到後面有個 lib64
的目錄名字。這裡重要的一點是 gcc 能在 /usr/lib
目錄下找到所有的三個 crt*.o
檔案。
驗證編譯器能搜尋正確的標頭檔案:
grep -B4 `^ /usr/include` dummy.log
這個命令應該返回下面的的輸出:
#include <...> search starts here:
/usr/lib/gcc/i686-pc-linux-gnu/4.9.2/include
/usr/local/include
/usr/lib/gcc/i686-pc-linux-gnu/4.9.2/include-fixed
/usr/include
同時,注意你的目標系統三段式後面的目錄名稱可能和上面的不同,這取決於你的架構。
注意
在版本 4.3.0 中,GCC 無條件安裝 limits.h
檔案到私有 include-fixed
目錄,要求這個目錄已經存在。
下一步,驗證新的連結器在使用正確的搜尋路徑:
grep `SEARCH.*/usr/lib` dummy.log |sed `s|; |
|g`
可以忽略指向含有 `-linux-gnu` 的路徑的引用,但最後一個命令的輸出應該是:
SEARCH_DIR("/usr/i686-pc-linux-gnu/lib32")
SEARCH_DIR("/usr/local/lib32")
SEARCH_DIR("/lib32")
SEARCH_DIR("/usr/lib32")
SEARCH_DIR("/usr/i686-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
64 位的系統可能有一些不同的目錄。例如,下面是一臺 x86_64 機器的輸出:
SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib64")
SEARCH_DIR("/usr/local/lib64")
SEARCH_DIR("/lib64")
SEARCH_DIR("/usr/lib64")
SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
然後確認我們使用了正確的 libc:
grep "/lib.*/libc.so.6 " dummy.log
最後一個命令的輸出(64 位主機中應該是 lib64 目錄)應該是:
attempt to open /lib/libc.so.6 succeeded
最後,確認 GCC 在使用正確的動態連結器:
grep found dummy.log
最後一個命令的輸出應該是(平臺相關的動態連結器是可以有所差異, 64 位系統中應該是 lib64 目錄):
found ld-linux.so.2 at /lib/ld-linux.so.2
如果輸出和上面的不一樣或者根本就沒有任何輸出,表明發生了很嚴重的錯誤。檢查並回溯步驟找出問題所在並糾正它。最可能的原因是配置檔案調整時出現了問題。在進入下一步之前必須解決所有的問題。
當一切都正常工作後,清理測試檔案:
rm -v dummy.c a.out dummy.log
最後,移動位置放錯的檔案:
mkdir -pv /usr/share/gdb/auto-load/usr/lib
mv -v /usr/lib/*gdb.py /usr/share/gdb/auto-load/usr/lib