1987-GCC#
案件摘要#
1983 年,Symbolics 倒閉與 MIT AI Lab 印表機驅動程式事件,讓 Richard Stallman 親身體悟專有軟體之害——連修復自己實驗室的機器都要被授權條款綁死。他決心先造「自由軟體的基石」:編譯器。1987 年,GNU C Compiler(GCC)1.0 發布,以 GPL 授權讓「自由」可以像病毒一樣傳染。GCC 從一個 C 編譯器長成支援多語言、多平台的巨獸,成為 Linux 世界與整個開源編譯基礎建設的起點——這是一場以程式碼為武器的自由之戰。
前因 -- 為什麼會有這個案子#
- Symbolics 與 AI Lab 的崩解:1980 年代初,MIT AI Lab 的駭客們被 Symbolics 等公司挖走;Stallman 獨自對抗 Symbolics 對 Lisp machine 作業系統的修改(1982-83),最終寡不敵眾。
- 印表機驅動程式事件:Xerox 送給 AI Lab 一台雷射印表機,驅動程式有臭蟲;Stallman 想修改原始碼,卻發現無法取得——「我曾有過整個社會的原始碼,一夕之間全被鎖進抽屜」。這成為他投身自由軟體運動的臨界點。
- GNU 計畫需要編譯器:1983 年 Stallman 發起 GNU(GNU's Not Unix)計畫,目標打造完全自由的 Unix 替代系統。構建系統的第一步就是編譯器——沒有自由的編譯器,整個系統都得依賴專有工具。
- 現成工具的侷限:當時有 Free University of Berlin 的 Pastel 編譯器(Stallman 曾參與開發)與 Allan Snyder 的 Portable C Compiler(PCC)概念可參考,但都不夠好——Stallman 決定親自打造。
線索與推理 -- 數學式、程式、理論#
前端/中端/後端分離:可移植性的抽象#
GCC 採用(並推廣了)編譯器的三段式分離架構:語言前端只產生中間表示(IR),目標機器後端只消費 IR。若語言數為 \(m\) 、目標機器數為 \(n\) :
當 \(m, n\) 都很大時, \(m + n \ll m \times n\) ——這個複雜度等級的差異,就是 GCC 能「一個編譯器打天下」的數學根源。GNU 編譯器套件(GCC 的 G 後來從 "GNU C" 改解為 "GNU Compiler Collection")正是靠這個架構長成巨獸。
GCC 編譯流程:-E/-S/-c 的階段之旅#
# GCC 把編譯拆成可單獨觀察的階段:
gcc -E hello.c -o hello.i # 預處理(preprocess):展開 #include 與巨集
gcc -S hello.i -o hello.s # 編譯(compile):前端解析 + 中端優化 -> 組合語言
gcc -c hello.s -o hello.o # 組譯(assemble):組合語言 -> 目標碼(機器碼)
gcc hello.o -o hello # 連結(link):合併目標檔與函式庫 -> 可執行檔
# 一步到位等價於: gcc hello.c -o hello
每個旗標對應管線的一個階段,可單獨執行、單獨檢查——這是龍書(1977)管線抽象的工程實現:-E 後可看到純 C 原始碼,-S 後可檢查組合語言是否優化得當,-c 後可用 nm 檢查符號表。
中間表示 RTL:三段式的樞紐#
GCC 內部以 RTL(Register Transfer Language) 作為核心中間表示,用 LISP 風格的 S-表達式描述每條指令的資料轉移:
; RTL 範例:把暫存器 r1 加上常數 4,結果存回 r1
; 對應 C: r1 = r1 + 4; (再由後端轉成 x86 的 add eax, 4)
(set (reg:SI 1)
(plus:SI (reg:SI 1)
(const_int 4)))
; 後端的任務:把 RTL 匹配到目標機器的指令模式(machine description, .md 檔)
; x86 後端定義:(define_insn "addsi3" ... "add{l}\\t{%1, %0|%0, %1}")
RTL 是一種「機器無關又機器可及」的語言:前端不需知道 x86 的存在,後端不需知道 C 語言的存在——一切溝通都透過 RTL。GCC 的 .md 檔(機器描述)為每個目標平台定義指令模式,新增一個後端只需寫一份 .md 檔,這就是 \(m+n\) 優勢的落地。
GPL copyleft:自由的法律邏輯#
Stallman 的創新不只在程式碼,更在授權的法律邏輯。copyleft(著作權反向使用)的推理結構:
令 P(x) = 「x 是 GPL 授權軟體」
令 F(x) = 「x 保有原始碼與修改再散布的自由」
公理 1:P(x) => F(x) (GPL 授權即自由)
公理 2:x 以 GPL 散布,且 y 是 x 的衍生作品 => P(y) (傳染條款)
推論:任何基於 GPL 軟體的修改與衍生,都必須以 GPL 釋出。
=> 自由不會被專有化吞噬,且隨著軟體被使用而擴散。
關鍵在公理 2:一般開放授權允許衍生作品改用專有授權(自由可被截斷),GPL 強制衍生作品維持同樣的自由——「自由」成為一個閉包運算:一旦進入 GPL 生態,所有衍生都留在生態內。這是 Stallman 用法律寫出的不動點定理。
結案 -- 後果與影響#
- 自由軟體運動的基石:1987 GCC 1.0 發布後,GNU 系統的其餘組件(GNU Emacs、Bash、glibc)陸續到位;1991 年 Linus Torvalds 的 Linux kernel 正是用 GCC 編譯、以 GPL 授權釋出——兩者合體成為完整的 GNU/Linux 系統。
- 多語言多平台巨獸:GCC 從 C 編譯器成長為支援 C、C++、Fortran、Ada、Go、Rust(gccrs)等語言、數十種處理器架構的編譯器套件;幾乎所有 Unix-like 系統的預設編譯器。
- 開源編譯基礎建設的起點:LLVM(2003)雖採不同授權(Apache 2.0)與更現代的 IR 設計,但其三段式架構思想直接承襲 GCC;今日 LLVM 支撐 Swift、Rust、Julia 等語言——無論 LLVM 或 GCC,都是 Stallman 當年「三段式 + 自由」推理的後裔。
- GPL 的傳染效應:GPL 成為全球最廣泛使用的自由軟體授權,Linux kernel、Git、Bash 皆在其下;v2(1991)與 v3(2007)持續對抗 Tivoization 等新形態的專有化。
- Stallman 的獎項:1990 年獲 MacArthur「天才獎」、ACM Grace Hopper 獎;2016 年入選 Internet Hall of Fame——自由軟體從意識形態運動長成了整個數位世界的地基。
關鍵人物與文獻#
- Richard Stallman(MIT AI Lab → GNU/FSF):GCC 作者、GPL 與 copyleft 的設計者、自由軟體運動創始人。
- Allan Snyder:Portable C Compiler 概念的先驅,影響 GCC 的可移植性設計。
- Linus Torvalds:1991 年以 GPL 釋出 Linux kernel,與 GCC 合體完成 GNU 系統。
- 文獻:
- R. Stallman, GNU Manifesto, 1985.
- R. M. Stallman and the GCC Developer Community, GNU Compiler Collection Internals, Free Software Foundation.
- R. Stallman, "The GNU Operating System and the Free Software Movement," in Open Sources, O'Reilly, 1999.
- GNU General Public License, Version 2, 1991; Version 3, 2007.