本文為gcc installation guide之中譯本,版權所有,譯者允許本文在網際網路上作免費之流傳、復制,然除經譯者允許外,禁止任何商業使用。
譯者:工技資管所 陳振宇 [email protected]
交大資管所 宋振華 [email protected]
如有任何疏失、錯漏,歡迎指正 7/1/1997
[編者:參見http://www.lslnet.com/linux/books/howto/GCC-HOWTO.html]
這是一份在Unix系統上安裝GNU CC的程序,VMS系統的使用者請看*注解:VMS 安裝。在這一節中,我們假設編譯的動作是在和原始檔案相同的目錄下執行;如果希望在其他目錄下執行編譯動作,請看 *注解:其他目錄。
在MS-DOS下直接安裝 GNU CC 是不可行的,使用 DOS 下的任何編譯器皆無法成功的編譯 GNU CC,除非你使用 GNU CC 本身。欲在 MS-DOS 下安裝 GNU CC,你必需取得已完全編譯完成的套件:DJGPP。DJGPP 中含有機器碼檔案以及原始程式檔,並且還包含了所有必需的編譯工具及函式庫。
1.如果你是在另外一部機器上,在同一目錄下先完成了GNU CC的編譯,執行 "make distclean" 來刪除一些可能無用的檔案。其中一個被刪除的檔案叫做 "Makefile";如果 "make distclean" 回應 Makefile 不存在(not exist)的訊息,那可能表示這個目錄已經被適當的清理完畢。
2.在 System V Release 4 系統上,請確定在路徑 "PATH" 設定中,"/usr/bin" 在 "/usr/ucb" 之前。因為 "/usr/ucb" 中的 cc 使用了有錯誤的函式庫。
3.你可以執行 "configure" 這支程式來設定 host machine、build machine、及 target machine。
所謂的 "build machine" 指的是你目前正在使用的機器;而"host machine" 則是你期望編譯後所產生的編譯器工作的機器;最後 "target machine" 則是你期望這個編譯器(正在做編譯的那個)產生的目的碼的主機。(一般而言,前兩者是相同的)。
如果你正在建立一的產生它自己執行的機器的目的碼的編譯器(native compiler),一般而言,不需要在 "configure" 作任何的設定;它將以目前正在使用的機器作為 host、build 及target machine。所以當你制作 native compiler 的時候,不需作任何設定。除非 "configure" 無法指出你的系統組態或是它猜錯了。
這樣的情況下,用選項 --build 指定 build machine 的"configuration name"; host 及 target machine 將預設和 build machine相同。(若你正在建立的是一個交互編譯器,請看
*注解:交互編譯器)
底下是一個例子:
./configure --build=sparc-sun-sunos4.1
建置名 (configuration name) 可能是一個標准的形式或者是標准形式的縮寫。
一個完整的建置名有由 "-" 號分開的三個部份。大概是:"CPU名稱-廠商名稱-系統名稱"(每一個部份可含有自己的"-" 號,configure 這個程式會自行分辨之)。舉例來說:"m68k-sun-sunos4.1" 是指 Sun 3。
你也可以用別名取代部份的建置名。例如: `sun3' 就代表了 `m68k-sun',`sun3-sunos4.1' 也是另一種 Sun 3 的表示方法。你也可以簡單點用`sun3-sunos',因為這邊假設 SunOS 的版本預設為 4. `sun3-bsd' 也可以,因為 `configure' 知道 SunOS 是 Sun 3 上唯一的 BSD 變種。
你可以在各種系統型態後面注明版本號碼,及 CPU 型號。在大部份的例子當中,版本是沒用的,而且會被忽略掉。所以如果你知道的話,最好也把號碼加上去。(ranma 注:這段原文怪怪的)
關於所支援的建置名與建置的相關注解,請參考 *注解:建置。在繼續安裝GNU CC 之前,你最好看一下那份注解。
底下有四種附加的選項可以讓你分別指定不同的硬體與軟體建置:
`--with-gnu-as', `with-gnu-ld`, `--with-stabs' 及 `--nfp'。
`--with-gnu-as'
如果你想要將 GNU CC 拿來跟 GNU 組譯器 (GNU assembler) 並用的話,你可以在執行 `configure' 時加上 `--with-gnu-as' 這個選項。
使用這個選項並不會安裝 GAS。 它只是將 GNU CC 的輸出修改成可以和 GAS 並用而已。要不要安裝 GAS 由你自己決定。
相反地,如果你 *不要* 使用 GAS 而且在建構 GNU CC 時不注明`--with-gnu-as' 的話,你也要自己決定是不是要安裝 GAS。 GNU CC 會在各個目錄□找 `as' 這個程式,如果它找到了 GAS 的話,它會用GAS。如果你不確定 GNU CC 到底是找到哪一個組譯器來用的話,在執行 gcc 時加上 `-v' 這個選項。
會因為你是否使用 GAS 而產生不同變化的系統有:
`hppa1.0-ANY-ANY', `hppa1.1-ANY-ANY', `i386-ANY-sysv',
`i386-ANY-isc',
`i860-ANY-bsd', `m68k-bull-sysv', `m68k-hp-hpux',
`m68k-sony-bsd',
`m68k-altos-sysv', `m68000-hp-hpux', `m68000-att-sysv',
`ANY-lynx-lynxos', 及 `mips-ANY'). 對於其他系統,
`--with-gnu-as' 並不會造成影響。
上述系統中 (除了 HP-PA, 386 上的 ISC, 及 `mips-sgi-irix5.*'),如果你使用 GAS,你也應該要使用 GNU 連結器 (linker),也就是要注明 `--with-gnu-ld'。
`--with-gnu-ld'
如果你想要拿 GNU 連結器跟 GNU CC 並用的話,注明這個選項。
這個選項並不會安裝 GNU 連結器,它只是改變 GNU CC 的習性來配合 GNU 連結器而已。比較不同的是,它使得 `collet2' 這個程式不會被安裝。這個程式是在大部份的建構中拿來做系統連結器的前置處理用的。
`--with-stabs'
在大部份以 MIPS 為基礎的系統以及 Alpha 上,你必須指明要 GNU CC 產生出正規的 ECOFF 除錯格式,或是要 BSD 式的stabs 傳遞 ECOFF 的符號表。正規的 ECOFF 除錯格式並不能完整地處理 C 以外的語言。而 BSD stabs 格式可以處理其他語言,但只能
在 GNU 除錯器 (GNU debugger) 上面做。
在正常情況下,GNU CC 預設使用 ECOFF 除錯格式,如果你偏好 BSD stabs 格式,在編譯時注明 `--with-stabs'。
不管你在建立 GNU CC 時是選用哪一種預設值,使用者都可以用`-gcoff' 和 `-gstabs+' 這兩個選項來指定他所要用的除錯格式。
`--with-stabs' 在 386 上的 ISC 系統中有特別意義,當 `--with-gas' 也被用到時。它會選擇使用嵌在 COFF 輸出中的 stabs 除錯資訊(stabs debugging information embedded in COFF output) 。這類的除錯資訊也支援 C++,普通的 COFF 除錯資訊並不能做到。
`--with-stabs' 在跑 SVR4 的 386 系統中也有特殊意義。它選擇使用嵌在 ELF 輸出中的 stabs 除錯資訊。在 386 SVR4 平台上,目前的C++ 編譯器 (2.6.0 版) 並不支援 DWARF 除錯資訊。stabs 提供了另一個可以用的方法。它需要 GAS 和 GDB,因為正常的 SVR4 工具並不能產生或解譯 stabs 格式。
`--nfp'
在某些系統上,你必須藉由這個選項注明這台機器是否有浮點運算器。這些系統包括了 `m68k-sun-sunosN' 及 `m68k-isi-bsd'。目前`--nfp' 在其他系統上並沒有作用,雖然在別的系統上可能也可以有不同的效果。
`configure' 這個程式會去原始碼目錄底下的子目錄□面去找那些要跟GNU CC 整合的其他編譯器。例如 GNU 的 C++ 編譯器,G++,放在 `cp' 這個子目錄□。`configure' 會把建立這些編譯器的規則加到 `Makefile' 中。
底下我們會詳細說明所有 `configure' 會設定的檔案。在正常情況下,你不需要去擔心這些檔案。
* 會建立一個叫 `config.h' 的檔案,□面有一個 `#include' 記載了你將來要用來執行這個編譯器行的機器的頂層設定檔 (*注解:建置)。這個檔案用來定義 host machine 的資訊。其中包含 `tm.h'。
頂層設定檔放在 `config' 這個子目錄□。它都叫做 `xm-某某東西.h',通常是 `xm-機器名.h',但有些例外。
如果你的系統不支援符號連結 (symbolic link),你可以要設定 `config.h' 讓它包含一條 `#include' 指到適當的檔案。
* 會建立一個叫 `tconfig.h' 的檔案,它引入了 target machine 的頂層設定檔。這是為了要用來編譯一些要在那台機器上跑的程式。
* 會建立一個叫 `tm.h' 的檔案,它包含了 target machine 的機器描述巨集檔案 (machine-description macro file)。它應該是放在 `config' 子目錄中而且它的名字通常是 `機器名.h'。
* `configure' 這個命令檔也會在 `Makefile.in' 這個樣版檔上加入一些字來產生 `Makefile'。 這些額外的文字來自 `config' 目錄中叫做`t-TARGET' 及 `x-HOST' 的檔案。如果這些檔案不存在,那就表示不需要為 target 或 host machine 加上其他東西。
4. 安裝 GNU CC 的標准目錄是 `/usr/local/lib'。如果你打算安裝到別的地方,在執行 `configure' 的注明 `--previx=目錄'。`目錄' 是你打算用來取代 `/usr/local' 的目錄名稱,除了底下這個例外: 不管你的編譯器安裝在何處,`/usr/local/include' 都是會被加到找尋標頭檔的目錄。如果你不想要這樣,你可以用下面這個 `--local-prefix' 選項。
5. 指定 `--local-prefix=目錄',這樣可以讓你設定編譯器找尋標頭檔的路徑。而不是使用 `/usr/local/include'。
*只有* 在你的電腦上放你特殊的規格檔案有不同習慣 (不是 `/usr/local') 時,你才會需要 `--local-prefix' 這個選項。
*不要* 把 `/usr' 指定給 `--local-prefix'!你在 `--local-prefix' 所用的目錄 *必須不* 包含所有的系統標准標頭檔。如果它真的包含,某些程式會被編譯成錯的。(包括 GNU Emacs, 在某些目標機器上),因為這樣做會蓋掉或搞丟 `fixincludes' 所定的標頭檔案集。
6. 確定 Bison 剖析器產生機 (parser generator) 已經安裝。(如果 Bison 所產生出來的 `c-parse.c' 跟 `cexp.c' 這兩個檔案比 `c-parse.y' 跟`cexp.y' 還新,而且你不打算改這些 `.y' 檔的話,這步就不用做。在 1988 年 9 月 8 號之前的 Bison 版本會產生不正確的 `c-parse.c'。
7. 如果你選擇了一個需要其他 GNU 工具(像是 GAS 或 GNU 連結器) 而不是標准系統工具的組態來做 GNU CC 的話,記得在建立 GNU CC 的目錄底下安裝所需的工具,並命名為 `as', 'ld' 或其他相關名稱。這樣會使得編譯器會在編譯 `enquire' 時去找這些適當的工具。
或者是,你可以在做後來的編譯工作時把 `PATH' 環境變數值設成 GNU 工具在標准系統工具之前。
8. 建立這個編譯器。只要在編譯器目錄□打入 `make LANGUAGES=c' 就好了。
`LANGUAGES=c' 指明了只會編譯 C 編譯器。makefile 正常下會去編譯所有它支援的語言,目前是 C, C++ 和 Objective C。然而,只有 C 是你用其他非 GNU C 編譯器所編出來的會動的一個。再說,在這個階段編譯 C 以外的東西是在浪費時間。
通常,你可以打入這個參數 `LANGUAGES="LIST"' 指明你要的語言,其中"LIST" 是 `c', `c++' 和 `objective-c' 之一或多個。如果你在 GNU CC 原始碼目碌下有其他附加的 GNU 編譯器,你會可以加到 `LIST' □面。
忽略掉在編 `insn-emit.c' 時所有 "statement not reached" 的警告訊息,那是正常的。還有,警告訊息 "unknown escape sequence" 在編 `genopinit.c' 或是其他檔案是也是正常的。同理,你也可以不理那些在 `insn-emit.c' 和 `insn-recog.c' 的 "constant is so large that it is unsigned" 和 `enquire.o' □的關於 "comparison always being zero" 。其他編譯錯誤可能表示了移植到你的機器或作業系統時的錯誤,你應該仔細檢查並提出報告 (附注:蟲)。
有些要錢的編譯器因為它們本身的蟲或是限制,在編 GNU CC 時會失敗。例如Microsoft 的編譯器說會用光所有巨集空間。有的 Ultrix 的編譯器會用完表示式空間,你必需分開問題發生處的敘述。
9. 如果你在做交互編譯器,就此打住。 *附注:交互編譯器
10. 用底下這個命令把第一階段目的檔案和可執行檔案放到一個目錄:
make stage1
這些檔案會放到一個叫 `stage1' 的副目錄□。當安裝完成以後,你或許會用 `rm -r stage` 把這些檔案殺掉。
11. 如果你選擇了一個需要其他 GNU 工具(像是 GAS 或 GNU 連結器) 而不是標准系統工具的組態來做 GNU CC 的話,把這些要用的工具放在 `stage1' 子目錄下,並命名為 `as', `ld' 或相關檔名。這樣會使得在做下一階段時第一階段編譯器會在這□找適合的工具。
或者是,你可以在做後續的編譯工作時把 `PATH' 環境變數值設成 GNU 工具在標准系統工具之前。
12. 用底下這個命令叫這個編譯器自己再重新編譯一次:
make CC="stage1/xgcc -Bstage1/" CFLAGS="-g -O2"
這叫做建造第二階段編譯器。
上面這個命令會造出所有支援語言的編譯器。如果你不要全部都做,你可以用 `LANGUAGES="LIST"' 注明你要做的語言。 LIST 可以包含 `c', `c++', `objective-c' 和 `proto' 之一或多個,以空白分開。`proto' 是指`protoize' 和 `unprotoize' 這兩個程式,它們不是一個獨立的語言,但是你是用 `LANGUAGES' 決定要不要安裝它們。
如果你還要繼續做第三階段編譯器,那你只要在第二階段做出 C 語言就好了。
當你做完第二階段編譯器以後,如果磁碟空間快沒了,你可以砍掉 `stage1' 這個子目錄。
在沒有浮點運算硬體的 68000 或 68020 系統上,除非你已經選了一個預設沒有浮點運算器的 `tm.h' 檔,不然就用底下這個:
make CC="stage1/xgcc -Bstage1/" CFLAGS="-g -O2 -msoft-float"
13. 如果你想以叫這個編譯器再編譯它自己一次來測試它的話,把其他需要的GNU 工具 (像是 GAS 或 GNU linker) 放在 `stage2' 子目錄□,就像在你之前在 `stage1' 子目錄□做的一樣,然後:
make stage2
make CC="stage2/xgcc -Bstage2/" CFLAGS="-g -O2"
這叫做建造第三階段編譯器。 除了 `-B' 選項,編譯選項都跟你在做第二階段編譯器時一樣。但是 `LANGUAGES' 這個選項不一定要一樣。上面這個命令會做出所有支援的編譯器。如果你不要全部都做,你可以用如前所述的 `LANGUAGES="LIST"' 選項指定你要的語言。
如果你不需要安裝任何附加的 GNU 工具,你可能要用底下這個命令
make bootstrap LANGUAGES=LANGUAGE-LIST BOOT_CFLAGS=OPTION-LIST
而不是做 `stage1', `stage2',並執行它們做出來的東西。
14. 然後是比較第二階段目的檔跟最後的目的檔 -- 除了時間戳記 (time stamp) 之外,它們應該要一樣才對。
在某些系統上,有意義的比較目的檔是不可能的;它們總是顯示 "不同"。目前在 Solaris 和一些使用 ELF 目的檔格式的系統上都會發生。在某些版本的 SGI 機器上的 Irix 和 Alpha 系統上的 DEC Unix (OSF/1),你不可能不指定 `-save-temps' 而比較這些檔案。如果你在比較上出了錯,去看看上述個別系統的說明。你在其他系統上也可能發生類似問題。
用這個命令來比較檔案:
make compare
它會提到所有第二階段和第三階段的目的檔的不同。有任何不同的話,不管是多麽無害,都顯示 GNU CC 在第二階段把編譯器做錯了,所以有可能有嚴重的錯誤。你應該檢查並提出報告。(*附注:蟲)
如果你的系統不會在目的檔上放時間戳記,有一個比較快的方法來比較它們 (用 Bourne shell):
for file in *.o; do
cmp $file stage2/$file
done
如果你是在 MIPS 的機器上用了 `-mno-mips-tfile' 選項,你將沒辦法去比較這些檔案。
15. 打 `make install' 安裝編譯器驅動程式,這□面包括了編譯器的各個階段 (pass) 和執行時期支援。在 `CC', `CFLAG', `LANGUAGES' □用跟你在做編譯時用一樣的值。這樣做有個必需的理由是因為某些版本的make □面有蟲,會莫名其妙地重新編譯檔案。假如你指定了一樣的變數值,那些檔案會適當地被重編譯。
舉例來說,假如你已經建立好第二階段編譯器,你可以用底下的命令:
make install CC="stage2/xgcc -Bstage2/" CFLAGS="-g -O" LANGUAGES="LIST"
這樣做會把 `cc1',`cpp' 跟 `libgcc.a' 拷貝到`/usr/local/lib/gcc-lib/TARGET/VERSION' 這個目錄□,這個目錄是編譯器驅動程式用來找這些檔案的地方。TARGET 是你在執行 `configure' 時所指定的目標機器型態,而 VERSION 是 GNU CC 的版本號碼。這種命名方法是為了要使得不同版本及/或交互編譯器可以同時存在。
這樣做也會把驅動程式 `xgcc' 放在 `/usr/local/bin/gcc' □面,使得它在典型的執行搜尋路徑□出現。
在某些系統上,這個命令會使得某些檔案被重新編譯。這通常是 `make' 的錯。你可以忽略掉這個問題,或是使用 GNU Make。
*警告* Sun 的函式庫中的 `alloca' 是有錯的。要避免掉這個錯誤,確定你安裝了用 GNU CC 所編譯出來的 GNU CC 可執行檔。(就是說,第二階段或第三階段的可執行檔,而不是第一階段的) 它們會把 `alloca' 當成是內建函數,而不會用到函數庫中的那一個。
(通常最好是使用第二階段或第三階段所產生的 GNU CC 可執行檔,因為一般來說它們在執行上會比其他的編譯器快)
16. 如果你要用 C++,你大概也要安裝 libg++ 這套東西。它應該在你取得 GNU C 的同一個地方。由於 GNU C 沒有另外的 C 執行時期函式庫,所以它也不包含C++ 執行程式庫。所有的 I/O 函數、特殊類別函式庫等等都包含在 libg++ □面。