首頁  >  文章  >  運維  >  Linux下使用g++編譯C++方法

Linux下使用g++編譯C++方法

小云云
小云云原創
2018-03-26 09:32:142070瀏覽

本文主要和大家分享在Linux環境中用g++編譯C++的方法以及相關實例程式碼分享,有興趣的朋友學習下。希望能幫助大家。

單一原始檔案產生可執行程式

下面是儲存在檔案helloworld.cpp 中一個簡單的C++ 程式的程式碼:


/* helloworld.cpp */
#include <iostream>
int main(int argc,char *argv[])
{
  std::cout << "hello, world" << std::endl;
  return(0);
}

程式使用定義在頭檔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 <iostream>
class Speak
{
  public:
    void sayHello(const char *);
};

下面列出的是檔案speak.cpp 的內容:包含sayHello() 函數的函數體:


/* speak.cpp */
#include "speak.h"
void Speak::sayHello(const char *str)
{
  std::cout << "Hello " << str << "\n";
}

檔案hellospeak.cpp 內是一個使用Speak 類別的程式:


#
/* hellospeak.cpp */
#include "speak.h"
int main(int argc,char *argv[])
{
  Speak speak;
  speak.sayHello("world");
  return(0);
}

下面這條指令將上述兩個原始碼檔案編譯連結成一個單一的可執行程式:


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

PS:這裡說一下為什麼在指令中沒有提到“speak.h“該檔案(原因是:在“speak.cpp“中包含有”#include"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 <iostream>
void sayhello(void);
class Say {
  private:
    char *string;
  public:
    Say(char *str)
    {
      string = str;
    }
    void sayThis(const char *str)
    {
      std::cout << str << " from a static library\n";
    }
    void sayString(void);
};

下面是文件 say.cpp 是我们要加入到静态库中的两个对象文件之一的源码。它包含 Say 类中 sayString() 函数的定义体;类 Say 的一个实例 librarysay 的声明也包含在内:


/* say.cpp */
#include "say.h"
void Say::sayString()
{
  std::cout << string << "\n";
}
 
Say librarysay("Library instance of Say");

源码文件 sayhello.cpp 是我们要加入到静态库中的第二个对象文件的源码。它包含函数 sayhello() 的定义:


/* sayhello.cpp */
#include "say.h"
void sayhello()
{
  std::cout << "hello from a static library\n";
}

下面的命令序列将源码文件编译成对象文件,命令 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[])
{
  extern Say librarysay;
  Say localsay = Say("Local instance of Say");
  sayhello();
  librarysay.sayThis("howdy");
  librarysay.sayString();
  localsay.sayString();
  return(0);
}

该程序可以下面的命令来编译和链接:


$ g++ saymain.cpp libsay.a -o saymain

程序运行时,产生以下输出:


hello from a static library
howdy from a static library
Library instance of Say
Local instance of Say

ps:如果一个文件夹下有多个cpp文件需要编译的话,除了采用makefile的方式之外,还可以使用“g++ *.cpp -o hello",“hello为编译生成的可执行文件的名字”,编译时要确保cpp文件和他们各自所引用的头文件在同一个目录下。

相关推荐:

在Linux环境下g++编译GDAL动态库的操作方法

Linux下g++编译以及使用静态库和动态库的方法详解

Linux下如何实现C++操作Mysql数据库的详细介绍


以上是Linux下使用g++編譯C++方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn