g++編譯程序


1.安裝

sudo apt-get install build-essential
# 查看 gcc 版本 然后安裝 統一版本的 g++
sudo apt-get install g++-7.3.0
gcc --version
gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

2.單個cpp文件生成可執行程序

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

在終端執行

$ g++ helloworld.cpp

編譯器默認的動作:編譯源代碼文件生成對象文件(object file),鏈接對象文件和 libstdc++ 庫中的函數得到可執行程序。然后刪除對象文件。由於命令行中未指定可執行程序的文件名,編譯器采用默認的 a.out。程序可以這樣來運行:

$ ./a.out
hello, world!

使用-o選項能夠指定可執行程序的文件名

$ g++ helloworld.cpp -o helloworld

在命令行中輸入程序名可使之運行:

$ ./helloworld
hello, world!

程序 g++ 是將 gcc 默認語言設為 C++ 的一個特殊的版本,鏈接時它自動使用 C++ 標准庫而不用 C 標准庫。通過遵循源碼的命名規范並指定對應庫的名字,用 gcc 來編譯鏈接 C++ 程序是可行的,如下例所示:

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

3.多個源文件生成可執行

如果多於一個的源碼文件在 g++ 命令中指定,它們都將被編譯並被鏈接成一個單一的可執行文件。

test.h

#include <iostream>
class test
{
    public:
        void say(const char *);
};

test.cpp

#include "speak.h"
void test::say(const char *str)
{
    std::cout << "Hello " << str << "\n";
}

main.cpp

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

編譯鏈接成一個單一的可執行程序

$ g++ test.cpp main.cpp -o main

4.源文件生成對象文件

選項 -c 用來告訴編譯器編譯源代碼但不要執行鏈接,輸出結果為對象文件。文件默認名與源碼文件名相同,只是將其后綴變為 .o。例如,下面的命令將編譯源碼文件 helloworld.cpp 並生成對象文件 helloworld.o:

$ g++ -c helloworld.cpp

5. 編譯預處理

選項 -E 使 g++ 將源代碼用編譯預處理器處理后不再執行其他動作。下面的命令預處理源碼文件 helloworld.cpp 並將結果顯示在標准輸出中:

$ g++ -E helloworld.cpp

預處理過的文件的 GCC 后綴為 .ii,它可以通過 -o 選項來生成,例如:

$ gcc -E helloworld.cpp -o helloworld.ii

6.生成匯編代碼

g++ -S helloworld.cpp

生成的匯編語言依賴於編譯器的目標平台

7.創建靜態庫

靜態庫是編譯器生成的一系列對象文件的集合。鏈接一個程序時用庫中的對象文件還是目錄中的對象文件都是一樣的。庫中的成員包括普通函數,類定義,類的對象實例等等。靜態庫的另一個名字叫歸檔文件(archive),管理這種歸檔文件的工具叫 ar

在下面的例子中,我們先創建兩個對象模塊,然后用其生成靜態庫。

頭文件 say.h 包含函數 sayHello() 的原型和類 Say 的定義:

#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 的聲明也包含在內:

#include "say.h"
void Say::sayString()
{
    std::cout << string << "\n";
}

Say librarysay("Library instance of Say");

下面的命令序列將源碼文件編譯成對象文件,命令 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

如果一個文件夾下有多個cpp文件需要編譯的話,除了采用makefile的方式之外,還可以使用“g++ *.cpp -o hello”,“hello為編譯生成的可執行文件的名字”,編譯時要確保cpp文件和他們各自所引用的頭文件在同一個目錄下。

 


免責聲明!

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



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