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文件和他们各自所引用的头文件在同一个目录下。

 

posted @ 2019-08-01 19:59  秦沐  阅读(2820)  评论(1编辑  收藏