單個原始檔生成可執行程式
下面是乙個儲存在檔案 helloworld.cpp 中乙個簡單的 c++ 程式的**:
/* helloworld.cpp */
#include
int main(int argc,char *argv)
程式使用定義在標頭檔案 iostream 中的 cout,向標準輸出寫入乙個簡單的字串。該**可用以下命令編譯為可執行檔案:
$ g++ helloworld.cpp
編譯器 g++ 通過檢查命令列中指定的檔案的字尾名可識別其為 c++ 源**檔案。編譯器預設的動作:編譯源**檔案生成物件檔案(object file),鏈結物件檔案和 libstdc++ 庫中的函式得到可執行程式。然後刪除物件檔案。由於命令列中未指定可執行程式的檔名,編譯器採用預設的 a.out。程式可以這樣來執行:
$ ./a.out
hello, world
更普遍的做法是通過 -o 選項指定可執行程式的檔名。下面的命令將產生名為 helloworld 的可執行檔案:
$ g++ helloworld.cpp -o helloworld
在命令列中輸入程式名可使之執行:
$ ./helloworld
hello, world
程式 g++ 是將 gcc 預設語言設為 c++ 的乙個特殊的版本,鏈結時它自動使用 c++ 標準庫而不用 c 標準庫。通過遵循原始碼的命名規範並指定對應庫的名字,用 gcc 來編譯鏈結 c++ 程式是可行的,如下例所示:
$ gcc helloworld.cpp -lstdc++ -o helloworld
選項 -l (ell) 通過新增字首 lib 和字尾 .a 將跟隨它的名字變換為庫的名字 libstdc++.a。而後它在標準庫路徑中查詢該庫。gcc 的編譯過程和輸出檔案與 g++ 是完全相同的。
在大多數系統中,gcc 安裝時會安裝一名為 c++ 的程式。如果被安裝,它和 g++ 是等同,如下例所示,用法也一致:
$ c++ helloworld.cpp -o helloworld
多個原始檔生成可執行程式
如果多於乙個的原始碼檔案在 g++ 命令中指定,它們都將被編譯並被鏈結成乙個單一的可執行檔案。下面是乙個名為 speak.h 的標頭檔案;它包含乙個僅含有乙個函式的類的定義:
/* speak.h */
#include
class speak
;下面列出的是檔案 speak.cpp 的內容:包含 sayhello() 函式的函式體:
/* speak.cpp */
#include "speak.h"
void speak::sayhello(const char *str)
檔案 hellospeak.cpp 內是乙個使用 speak 類的程式:
/* hellospeak.cpp */
#include "speak.h"
int main(int argc,char *argv)
下面這條命令將上述兩個原始碼檔案編譯鏈結成乙個單一的可執行程式:
$ g++ hellospeak.cpp speak.cpp -o hellospeak
ps:這裡說一下為什麼在命令中沒有提到「speak.h「該檔案(原因是:在「speak.cpp「中包含有」#include"speak.h"「這句**,它的意思是搜尋系統頭檔案目錄之前將先在當前目錄中搜尋檔案「speak.h「。而」speak.h「正在該目錄中,不用再在命令中指定了)。
原始檔生成物件檔案
選項 -c 用來告訴編譯器編譯源**但不要執行鏈結,輸出結果為物件檔案。檔案預設名與原始碼檔名相同,只是將其字尾變為 .o。例如,下面的命令將編譯原始碼檔案 hellospeak.cpp 並生成物件檔案 hellospeak.o:
$ g++ -c hellospeak.cpp
命令 g++ 也能識別 .o 檔案並將其作為輸入檔案傳遞給鏈結器。下列命令將編譯原始碼檔案為物件檔案並將其鏈結成單一的可執行程式:
$ g++ -c hellospeak.cpp
$ g++ -c speak.cpp
$ g++ hellospeak.o speak.o -o hellospeak
選項 -o 不僅僅能用來命名可執行檔案。它也用來命名編譯器輸出的其他檔案。例如:除了中間的物件檔案有不同的名字外,下列命令生將生成和上面完全相同的可執行檔案:
$ g++ -c hellospeak.cpp -o hspk1.o
$ g++ -c speak.cpp -o hspk2.o
$ g++ hspk1.o hspk2.o -o hellospeak
編譯預處理
選項 -e 使 g++ 將源**用編譯預處理器處理後不再執行其他動作。下面的命令預處理原始碼檔案 helloworld.cpp 並將結果顯示在標準輸出中:
$ g++ -e helloworld.cpp
本文前面所列出的 helloworld.cpp 的源**,僅僅有六行,而且該程式除了顯示一行文字外什麼都不做,但是,預處理後的版本將超過 1200 行。這主要是因為標頭檔案 iostream 被包含進來,而且它又包含了其他的標頭檔案,除此之外,還有若干個處理輸入和輸出的類的定義。
預處理過的檔案的 gcc 字尾為 .ii,它可以通過 -o 選項來生成,例如:
$ gcc -e helloworld.cpp -o helloworld.ii
生成彙編**
選項 -s 指示編譯器將程式編譯成組合語言,輸出組合語言**而後結束。下面的命令將由 c++ 原始碼檔案生成組合語言檔案 helloworld.s:
$ g++ -s helloworld.cpp
生成的組合語言依賴於編譯器的目標平台。
建立靜態庫
靜態庫是編譯器生成的一系列物件檔案的集合。鏈結乙個程式時用庫中的物件檔案還是目錄中的物件檔案都是一樣的。庫中的成員包括普通函式,類定義,類的物件例項等等。靜態庫的另乙個名字叫歸檔檔案(archive),管理這種歸檔檔案的工具叫 ar 。
在下面的例子中,我們先建立兩個物件模組,然後用其生成靜態庫。
標頭檔案 say.h 包含函式 sayhello() 的原型和類 say 的定義:
/* say.h */
#include
void sayhello(void);
class say
void saythis(const char *str)
void saystring(void);
};下面是檔案 say.cpp 是我們要加入到靜態庫中的兩個物件檔案之一的原始碼。它包含 say 類中 saystring() 函式的定義體;類 say 的乙個例項 librarysay 的宣告也包含在內:
/* say.cpp */
#include "say.h"
void say::saystring()
say librarysay("library instance of say");原始碼檔案 syshello.cpp 是我們要加入到靜態庫中的第二個物件檔案的原始碼。它包含函式 sayhello() 的定義:
/* sayhello.cpp */
#include "say.h"
void sayhello()
下面的命令序列將原始碼檔案編譯成物件檔案,命令 ar 將其存進庫中:
$ g++ -c sayhello.cpp
$ g++ -c say.cpp
$ ar -r libsay.a sayhello.o say.o
程式 ar 配合引數 -r 建立乙個新庫 libsay.a 並將命令列中列出的物件檔案插入。採用這種方法,如果庫不存在的話,引數 -r 將建立乙個新的庫,而如果庫存在的話,將用新的模組替換原來的模組。
下面是主程式 saymain.cpp,它呼叫庫 libsay.a 中的**:
/* saymain.cpp */
#include "say.h"
int main(int argc,char *argv)
$ g++ saymain.cpp libsay.a -o saymain
程式執行時,產生以下輸出:
hello from a static library
howdy from a static library
library instance of saylocal instance of say
gcc編譯C 程式
單個原始檔生成可執行程式 下面是乙個儲存在檔案 helloworld.cpp 中乙個簡單的 c 程式的 helloworld.cpp include int main int argc,char argv 程式使用定義在標頭檔案 iostream 中的 cout,向標準輸出寫入乙個簡單的字串。該 可...
gcc編譯C 程式
單個原始檔生成可執行程式 下面是乙個儲存在檔案 helloworld.cpp 中乙個簡單的 c 程式的 helloworld.cpp include int main int argc,char ar std cout hello,world std endl return 0 程式使用定義在標頭檔...
gcc編譯c語言程式
編譯 當前源 編譯成二進位制目標檔案 obj檔案 乙個現代編譯器的主要工作流程如下 源程式 source code 預處理器 preprocessor 編譯器 compiler 匯程式設計序 assembler 目標程式 object code 聯結器 鏈結器,linker 可執行程式 execut...