Linux環境使用g 編譯C

2021-10-14 11:02:19 字數 3900 閱讀 1492

以下述c++**的編譯為例

/* helloworld.cpp */

#include

intmain

(int argc,

char

*ar**)

該**可用以下命令編譯:

$ g++ helloworld.cpp

編譯器 g++ 通過檢查命令列中指定的檔案的字尾名,可識別其為 c++ 源**檔案。

編譯器預設的動作:編譯源**檔案生成物件檔案(object file),鏈結物件檔案和 libstdc++ 庫中的函式得到可執行程式。然後刪除物件檔案。

因為未指定可執行程式的檔名,編譯器採用預設的 a.out。程式可以這樣來執行:

$ ./a.out

hello, world

更普遍的做法,通過 -o 選項指定可執行程式的檔名。

$ g++ helloworld.cpp -o helloworld

輸入程式名可使之執行:

$ ./helloworld

hello, world

拓展,用gcc編譯:程式 g++ 是將 gcc 預設語言設為 c++ 的乙個特殊的版本,鏈結時它自動使用 c++ 標準庫而不用 c 標準庫。

通過遵循原始碼的命名規範並指定對應庫的名字,用 gcc 來編譯鏈結 c++ 程式是可行的,如下例所示:

$ gcc helloworld.cpp -lstdc++ -o helloworld

選項 -l (ell) 通過新增字首 lib 和字尾 .a 將跟隨它的名字變換為庫的名字 libstdc++.a。而後它在標準庫路徑中查詢該庫。

在大多數系統中,gcc 安裝時會安裝一名為 c++ 的程式。如果被安裝,它和 g++ 是等同,如下例所示,用法也一致:

$ c++ helloworld.cpp -o helloworld

如果多於乙個的原始碼檔案在 g++ 命令中指定,它們都將被編譯並被鏈結成乙個單一的可執行檔案。

/* speak.h */

#include

class

speak

;/* speak.cpp */

#include

"speak.h"

void speak::

sayhello

(const

char

*str)

/* hellospeak.cpp */

#include

"speak.h"

intmain

(int argc,

char

*ar**)

編譯命令:

$ g++ hellospeak.cpp speak.cpp -o hellospeak

ps:這裡說一下為什麼在命令中沒有提到「speak.h「該檔案(原因是:在「speak.cpp「中包含有」#include"speak.h"「這句**,它的意思是搜尋系統頭檔案目錄之前將先在當前目錄中搜尋檔案「speak.h「。而」speak.h「正在該目錄中,不用再在命令中指定了)。

選項 -c 用來告訴編譯器編譯源**但不要執行鏈結,輸出結果為物件檔案。通過下面命令,編譯原始碼檔案 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

sayvoid

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"

);

原始碼檔案 sayhello.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"

intmain

(int argc,

char

*ar**)

{extern say librarysay;

say localsay =

say("local instance o

Linux 環境下使用g 編譯C

下面是乙個儲存在檔案 helloworld.cpp 中乙個簡單的 c 程式的 helloworld.cpp include int main int argc,char argv 程式使用定義在標頭檔案 iostream 中的 cout,向標準輸出寫入乙個簡單的字串。該 可用以下命令編譯為可執行檔案...

Linux環境g 編譯TinyXML動態庫

除了cmarkup,tinyxml也是c c 下解析xml很好的工具。在linux下用g 編譯tinyxml的步驟如下 tinyxml版本2.6.2 進入tinyxml解壓目錄,用文字編輯器開啟makefile檔案。修改編譯目的檔案引數。將output xmltest改為output libtiny...

Ubuntu環境下使用g 編譯cpp檔案

第一次用g 編譯cpp檔案的時候報了undefined reference的錯誤,自定義類中的函式全部都無法找到,查詢資料後發現呼叫的類是需要鏈結的,本文以乙個小例子描述編譯的過程。其中class2類呼叫了class1類的成員函式,依賴於class1類,而test檔案呼叫了class2類的成員函式,...