GNU、GPL、FSF、GCC概述


百度詞條

  • GNU:GNU是一個自由的操作系統,其內容軟件完全以GPL方式發布。這個操作系統是GNU計划的主要目標,名稱來自GNU's Not Unix!的遞歸縮寫,因為GNU的設計類似Unix,但它不包含具著作權的Unix代碼。GNU的創始人是理查德·馬修·斯托曼。
  • GPL:GNU通用公共許可證簡稱為GPL,是由自由軟件基金會發行的用於計算機軟件的協議證書,使用該證書的軟件被稱為自由軟件。大多數的GNU程序和超過半數的自由軟件使用它。
  • FSF:自由軟件基金會(Free Software Foundation,FSF)是一個致力於推廣自由軟件、促進計算機用戶自由的美國民間非盈利性組織。它於1985年10月由理查德·斯托曼建立。其主要工作是執行GNU計划,開發更多的自由軟件,完善自由軟件理念。
  • GCC:GCC(GNU Compiler Collection,GNU編譯器套件)是由GNU開發的編程語言譯器。GNU編譯器套件包括C、C++、 Objective-C、 Fortran、Java、Ada和Go語言前端,也包括了這些語言的庫(如libstdc++,libgcj等。)

GUN計划(GNU工程)產出了很多自由軟件,包括GNU操作系統、GCC編譯器套件、GDB等。可以說在GPL條例下發布的軟件都可以說是自由軟件。

理查德·馬修·斯托曼(Richard Matthew Stallman, RMS)

GNU、GPL、FSF、GCC全部和一個人有關,就是理查德·馬修·斯托曼(Richard Matthew Stallman, RMS),斯托曼於1953年出生,自由軟件運動的精神領袖、GNU計划以及自由軟件基金會(Free Software Foundation)的創立者、著名黑客。
作為自由軟件運動的精神領袖,他所建立的GNU工程激勵了很多的年輕黑客,這些人也創作了很多自由軟件。 他所寫作的GNU通用公共許可證(GPL)是世上最廣為采用的自由軟件許可證,為copyleft觀念開拓出一條嶄新的道路。

經歷

斯托曼1953年出生於美國紐約曼哈頓地區,1971年進入哈佛大學學習,同年受聘於麻省理工學院人工智能實驗室(AI Laboratory),成為一名職業黑客。 在AI實驗室工作期間,斯托曼開發了多種今后影響深遠的軟件,其中最著名的就是Emacs。斯托曼在AI是一名典型的黑客,是整個黑客文化的一份子。
然而進入八十年代后,軟件進入版權時代,黑客社群在軟件工業商業化的強大壓力下日漸土崩瓦解,甚至連AI實驗室的許多黑客也組成了Symbolic公司,試圖以專利軟件來取代實驗室中黑客文化的產物-免費可自由流通的軟件。
斯托曼對此感到氣憤與無奈。在對Symbolic進行了一段時間的抗爭后,他於1985年發表了著名的GNU宣言(GNU Manifesto),正式宣布要開始進行一項宏偉的計划:創造一套完全自由免費,兼容Unix的操作系統GNU(GNU's Not Unix!)。之后他又建立了自由軟件基金會來協助該計划。
他於1989年與一群律師起草了廣為使用的GNU通用公共協議證書(GNU General Public License, GNU GPL),創造性地提出了“反版權”(或“版權屬左”,或“開權”,copyleft)的概念。 同時,GNU計划中除了最關鍵的Hurd操作系統內核之外,其他絕大多數軟件已經完成。
1991年芬蘭大學生Linus Torvalds在GPL條例下發布他自己創作的Linux操作系統內核,至此GNU計划正式完成,操作系統被命名為GNU/Linux(或簡稱Linux)。
斯托曼是一名堅定的自由軟件運動倡導者與其他提倡開放源代碼的人不同,斯托曼並不是從軟件質量的角度而是從道德的角度來看待自由軟件。他認為使用專利軟件是非常不道德的事,只有附帶了源代碼的程序才是符合其道德標准的。對此許多人表示異議,並也因此有了自由軟件運動與開源軟件運動之分。

GCC

GCC是以GPL許可證所發行的自由軟件,也是GNU計划的關鍵部分。GCC的初衷是為GNU操作系統專門編寫一款編譯器,現已被大多數類Unix操作系統(如Linux、BSD、MacOS X等)采納為標准的編譯器,甚至在微軟的Windows上也可以使用GCC。GCC支持多種計算機體系結構芯片,如x86、ARM、MIPS等,並已被移植到其他多種硬件平台。
GCC原名為GNU C語言編譯器(GNU C Compiler),只能處理C語言。但其很快擴展,變得可處理C++,后來又擴展為能夠支持更多編程語言,如Fortran、Pascal、Objective -C、Java、Ada、Go以及各類處理器架構上的匯編語言等,所以改名GNU編譯器套件(GNU Compiler Collection) 。
基本用法
使用GCC編譯器的時候,我們必須給出一系列必要的調用參數和文件名稱。GCC編譯器的調用參數大約有100多個,這里只介紹其中最基本、最常用的參數。
GCC最基本的用法是∶gcc [options] [filenames]
其中options就是編譯器所需要的參數,filenames給出相關的文件名稱。

  • -c,僅執行編譯操作,不進行連接操作,不鏈接成為可執行文件,編譯器只是由輸入的.c等源代碼文件生成.o為后綴的目標文件,通常用於編譯不包含主程序的子程序文件。
  • -o output_filename,指定生成的輸出文件,確定輸出文件的名稱為output_filename,同時這個名稱不能和源文件同名。如果不給出這個選項,gcc就給出預設的可執行文件a.out。
  • -g,產生符號調試工具(GNU的gdb)所必要的符號資訊,要想對源代碼進行調試,我們就必須加入這個選項。
  • -O,對程序進行優化編譯、鏈接,采用這個選項,整個源代碼會在編譯、鏈接過程中進行優化處理,這樣產生的可執行文件的執行效率可以提高,但是,編譯、鏈接的速度就相應地要慢一些。
  • -O2,比-O更好的優化編譯、鏈接,當然整個編譯、鏈接過程會更慢。
  • -E:僅執行編譯預處理;
  • -S:將C代碼轉換為匯編代碼;
  • -wall:顯示警告信息;
  • -v gcc執行時執行的詳細過程,gcc及其相關程序的版本號

基本規則
gcc所遵循的部分約定規則:

  • .c為后綴的文件,C語言源代碼文件;
    .a為后綴的文件,是由目標文件構成的檔案庫文件;
    .C,.cc或.cxx 為后綴的文件,是C++源代碼文件且必須要經過預處理;
    .h為后綴的文件,是程序所包含的頭文件;
    .i 為后綴的文件,是C源代碼文件且不應該對其執行預處理;
    .ii為后綴的文件,是C++源代碼文件且不應該對其執行預處理;
    .m為后綴的文件,是Objective-C源代碼文件;
    .mm為后綴的文件,是Objective-C++源代碼文件;
    .o為后綴的文件,是編譯后的目標文件;
    .s為后綴的文件,是匯編語言源代碼文件;
    .S為后綴的文件,是經過預編譯的匯編語言源代碼文件。

執行過程
雖然我們稱GCC是C語言的編譯器,但使用gcc由C語言源代碼文件生成可執行文件的過程不僅僅是編譯的過程,而是要經歷四個相互關聯的步驟∶預處理(也稱預編譯,Preprocessing)、編譯(Compilation)、匯編(Assembly)和鏈接(Linking)。

命令gcc首先調用cpp進行預編譯,在預編譯過程中,對源代碼文件中的文件包含(include)、預編譯語句(如宏定義define等)進行分析,由.c為后綴的文件生成.i為后綴的文件。接着調用cc1進行編譯,這個階段根據輸入文件(xxx.i)生成以.s為后綴的目標文件。匯編過程是針對匯編語言的步驟,調用as進行工作,一般來講,.S.s為后綴的匯編語言源代碼文件都生成以.o為后綴的目標文件。當所有的目標文件都生成之后,gcc就調用ld來完成最后的關鍵性工作,這個階段就是鏈接。在鏈接階段,所有的目標文件被安排在可執行程序中的恰當的位置,同時,該程序所調用到的庫函數也從各自所在的檔案庫中連到合適的地方。

執行過程示例

  • 示例代碼,創建hello.txt文件,輸入以下內容,修改后綴為.c
#include<stdio.h>

int main(void)
{
	printf("hello world\n");
	return 0;
}
  • 預編譯過程
    這個過程處理宏定義和include,去除注釋,不會對語法進行檢查。
[root@localhost gcc-test]# cat hello.c | wc -l
6 // 可以看到hello.c文件目前是6行。
[root@localhost gcc-test]# 
[root@localhost gcc-test]# gcc -E hello.c -o hello.i
[root@localhost gcc-test]# ls
hello.c  hello.i  // 預編譯成功完成,生成hello.i文件
[root@localhost gcc-test]# cat hello.i | wc -l
843 // 可以看到預編譯后,代碼從6行擴展到了843行。
[root@localhost gcc-test]# 
  • 編譯過程
    這個階段,檢查語法,生成匯編代碼。
[root@localhost gcc-test]# gcc -S hello.i -o hello.s
[root@localhost gcc-test]# ls
hello.c  hello.i  hello.s
[root@localhost gcc-test]# cat hello.s | wc -l
26
[root@localhost gcc-test]# 
  • 匯編過程
    這個階段,生成目標代碼。
    此過程生成ELF格式的目標代碼。
[root@localhost gcc-test]# gcc -c hello.s -o hello.o
[root@localhost gcc-test]# ls
hello.c  hello.i  hello.o  hello.s
[root@localhost gcc-test]# file hello.o
hello.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
[root@localhost gcc-test]# 
  • 鏈接過程
    鏈接過程。生成可執行代碼。鏈接分為兩種,一種是靜態鏈接,另外一種是動態鏈接。使用靜態鏈接的好處是,依賴的動態鏈接庫較少,對動態鏈接庫的版本不會很敏感,具有較好的兼容性;缺點是生成的程序比較大。使用動態鏈接的好處是,生成的程序比較小,占用較少的內存。
[root@localhost gcc-test]# gcc hello.o -o hello
[root@localhost gcc-test]# ls
hello  hello.c  hello.i  hello.o  hello.s

程序運行:

[root@localhost gcc-test]# ./hello
hello world
[root@localhost gcc-test]# 

無選項編譯鏈接
gcc test.c
將test.c預處理、匯編、編譯並鏈接形成可執行文件。這里未指定輸出文件,默認輸出為a.out。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM