linux下使用g++编译cpp工程

C++编程中相关文件后缀

linux下使用g++编译cpp工程

1.单个源文件生成可执行程序

下面是一个保存在文件helloworld.cpp中一个简单的C++程序的代码:

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

程序使用定义在头文件iostream中的cout,向标准输出写入一个简单的字符串。该代码可用以下命令编译为可执行文件:

1 $ g++ helloworld.cpp

编译器g++通过检查命令行中指定的文件的后缀名可识别其为C++源代码文件。编译器默认的动作:编译源代码文件生成对象文件(object file),链接对象文件和libstdc++库中的函数得到可执行程序。然后删除对象文件。由于命令行中未指定可执行程序的文件名,编译器采用默认的a.out。程序可以这样来运行:

1 $ ./a.out
2 
3 hello, world

更普遍的做法是通过-o选项指定可执行程序的文件名。下面的命令将产生名为helloworld的可执行文件:

1 $ g++ helloworld.cpp -o helloworld

在命令行中输入程序名可使之运行:

1 $ ./helloworld
2 
3 hello, world

程序g++是将gcc默认语言设为C++的一个特殊的版本,链接时它自动使用C++标准库而不用C标准库。通过遵循源码的命名规范并指定对应库的名字,用gcc来编译链接C++程序是可行的,如下例所示:

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

选项-l (ell)通过添加前缀lib和后缀.a将跟随它的名字变换为库的名字libstdc++.a。而后它在标准库路径中查找该库。gcc的编译过程和输出文件与g++是完全相同的。

在大多数系统中,GCC安装时会安装一名为c++的程序。如果被安装,它和g++是等同,如下例所示,用法也一致:

1 $ c++ helloworld.cpp -o helloworld

2.多个源文件生成可执行程序

如果多于一个的源码文件在g++命令中指定,它们都将被编译并被链接成一个单一的可执行文件。下面是一个名为speak.h的头文件;它包含一个仅含有一个函数的类的定义:

1 /* speak.h */
2 #include <iostream>
3 class Speak
4 {
5     public:
6         void sayHello(const char *);
7 };

下面列出的是文件speak.cpp的内容:包含sayHello()函数的函数体:

1 /* speak.cpp */
2 #include "speak.h"
3 void Speak::sayHello(const char *str)
4 {
5     std::cout << "Hello " << str << "n";
6 }

文件hellospeak.cpp内是一个使用Speak类的程序:

1 /* hellospeak.cpp */
2 #include "speak.h"
3 int main(int argc,char *argv[])
4 {
5     Speak speak;
6     speak.sayHello("world");
7     return(0);
8 }

下面这条命令将上述两个源码文件编译链接成一个单一的可执行程序:

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

PS:这里说一下为什么在命令中没有提到“speak.h“该文件(原因是:在“speak.cpp“中包含有”#include"speak.h"“这句代码,它的意思是搜索系统头文件目录之前将先在当前目录中搜索文件“speak.h“。而”speak.h“正在该目录中,不用再在命令中指定了)。

3.源文件生成对象文件

选项-c用来告诉编译器编译源代码但不要执行链接,输出结果为对象文件。文件默认名与源码文件名相同,只是将其后缀变为.o。例如,下面的命令将编译源码文件hellospeak.cpp并生成对象文件hellospeak.o

1 $ g++ -c hellospeak.cpp

命令g++也能识别.o文件并将其作为输入文件传递给链接器。下列命令将编译源码文件为对象文件并将其链接成单一的可执行程序:

1 $ g++ -c hellospeak.cpp
2 
3 $ g++ -c speak.cpp
4 
5 $ g++ hellospeak.o speak.o -o hellospeak

选项-o不仅仅能用来命名可执行文件。它也用来命名编译器输出的其他文件。例如:除了中间的对象文件有不同的名字外,下列命令生将生成和上面完全相同的可执行文件:

1 $ g++ -c hellospeak.cpp -o hspk1.o
2 
3 $ g++ -c speak.cpp -o hspk2.o
4 
5 $ g++ hspk1.o hspk2.o -o hellospeak

4.编译预处理

选项-E使g++将源代码用编译预处理器处理后不再执行其他动作。下面的命令预处理源码文件helloworld.cpp并将结果显示在标准输出中:

1 $ g++ -E helloworld.cpp

本文前面所列出的helloworld.cpp的源代码,仅仅有六行,而且该程序除了显示一行文字外什么都不做,但是,预处理后的版本将超过1200行。这主要是因为头文件iostream被包含进来,而且它又包含了其他的头文件,除此之外,还有若干个处理输入和输出的类的定义。

预处理过的文件的GCC后缀为.ii,它可以通过-o选项来生成,例如:

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

5.生成汇编代码

选项-S指示编译器将程序编译成汇编语言,输出汇编语言代码而後结束。下面的命令将由C++源码文件生成汇编语言文件helloworld.s

1 $ g++ -S helloworld.cpp

生成的汇编语言依赖于编译器的目标平台。

6.创建静态库

静态库是编译器生成的一系列对象文件的集合。链接一个程序时用库中的对象文件还是目录中的对象文件都是一样的。库中的成员包括普通函数,类定义,类的对象实例等等。静态库的另一个名字叫归档文件(archive),管理这种归档文件的工具叫ar

在下面的例子中,我们先创建两个对象模块,然后用其生成静态库。

头文件say.h包含函数sayHello()的原型和类Say的定义:

1 /* say.h */
 2 #include <iostream>
 3 void sayhello(void);
 4 class Say {
 5     private:
 6         char *string;
 7     public:
 8         Say(char *str)
 9         {
10             string = str;
11         }
12         void sayThis(const char *str)
13         {
14             std::cout << str << " from a static libraryn";
15         }
16         void sayString(void);
17 };

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

1 /* say.cpp */
2 #include "say.h"
3 void Say::sayString()
4 {
5     std::cout << string << "n";
6 }
7 
8 Say librarysay("Library instance of Say");

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

1 /* sayhello.cpp */
2 #include "say.h"
3 void sayhello()
4 {
5     std::cout << "hello from a static libraryn";
6 }

下面的命令序列将源码文件编译成对象文件,命令ar将其存进库中:

1 $ g++ -c sayhello.cpp
2 
3 $ g++ -c say.cpp
4 
5 $ ar -r libsay.a sayhello.o say.o

程序ar配合参数-r创建一个新库libsay.a并将命令行中列出的对象文件插入。采用这种方法,如果库不存在的话,参数-r将创建一个新的库,而如果库存在的话,将用新的模块替换原来的模块。

下面是主程序saymain.cpp,它调用库libsay.a中的代码:

1 /* saymain.cpp */
 2 #include "say.h"
 3 int main(int argc,char *argv[])
 4 {
 5     extern Say librarysay;
 6     Say localsay = Say("Local instance of Say");
 7     sayhello();
 8     librarysay.sayThis("howdy");
 9     librarysay.sayString();
10     localsay.sayString();
11     return(0);
12 }

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

1 $ 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

原文地址:http://wiki.ubuntu.org.cn/Compiling_Cpp
原文链接: https://www.cnblogs.com/battlescars/p/cpp_linux_gcc.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/245217

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月14日 上午12:40
下一篇 2023年2月14日 上午12:40

相关推荐