Linux环境使用g++编译C++方法总结
作者:hnyzwtf 发布时间:2021-11-10 22:09:35
单个源文件生成可执行程序
下面是一个保存在文件 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“。而”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文件和他们各自所引用的头文件在同一个目录下。
来源:https://blog.csdn.net/hnyzwtf/article/details/44674145
猜你喜欢
- 当您试图利用FTP连接到一台远程计算机时,远程系统会向您要求一个用户名及口令,而在浩如烟海的Internet中要求每个用户向每个服务器系统申
- 无论你试图从即将坏掉的存储驱动器抢救数据,将归档备份到远程存储,还是在别处对活动分区制作一份完美副本,都要知道如何安全可靠地复制驱动器和文件
- 个人网站越来越多,据说现在中国个人站长已经超过了3200万。而且由于CN域名一元促销活动的推动,越来越多的网民走向了个人站长的道理。但是,网
- 各位站长好,以前给百度客服打过N次电话,每每问及近期收录相关事谊都不给允回答。今天又打了一次。接电话的是个男的,听声音好像未成年...(日小
- 我在最小化安装CentOS中网卡启动正常,但是当我们装了桌面版的CentOS后,发现不管使用哪种启动网卡的方式都会启动失败。截图如下:后来查
- 国外有很多的主机商都只是提供Linux的服务器,我看了有不少站长其实也是需要Windows的服务器的,比如你的网站是ASP.NET或者是AS
- 每当我提到我的博客的时候,人们总是抬一下眼皮,或者微笑一下,表示“我不太了解,不过还不错”。但是当我提到我从博客中赚到钱时,我突然发现,他们
- Apache Shiro的配置主要分为四部分:对象和属性的定义与配置URL的过滤器配置静态用户配置静态角色配置其中,由于用户、角色一般由后台
- 调试环境:Redhat9.0Apache1.3.29Mysql3.23.58PHP4.3.4Linux系统的安装我就不讲了,这是基本功,其实
- Google网站优化器 (Website Optimizer,WO)是一个强大的工具,允许站长分析网站流量,测试有效性和转化率等变量,一般情
- 访问 http://www.abc.com/course/ ,实际访问的是:d:/www/moodle/index.PHP<Virtu
- 最近发现Godaddy控制面板又更新了,搞的有些东西都不知道点哪里,呵呵,特此我们发表这篇文章,以后配置的时候直接来这里看方便广大Godad
- 前言linux权限多设的比较松的其实,但有的虚拟机还是不能跨目录访问的。在提不了权的情况下,试试如下代码吧。运气好的话说不定就跨过去了。下面
- 我做了如下测试:(1) http://www.xxx.com/new/new.asp?id=49’Microsoft OLE DB Prov
- 以前帮客户做好网站之后就轻松了,基本上不用再管,如果有什么问题,也只是负责修改某些功能而已,基本上牵扯不到网站的运营推广,哪些都是他们的事情
- 瑞典正在调查一件攻击网站的大案,访问靠前的多个媒体公司的网站当地时间周四被全面DDoS攻击,随后,瑞典警方的网站也在几个小时后瘫痪。警方表示
- 由于各种原因,我们有时候需要在一个IP地址上建立多个web站点,在IIS5中,我们可能通过简单的设置达到这个目标.在IIS中,每个 Web
- 一项专业的运动团体买了一个名牌服务器,但是它刚开始工作时就出问题。该网络管理员向操作系统厂商和硬件厂商提出帮助请求。6.设备转手次数太多,内
- 长时间对网络营销的关注,让我有了习惯性思维。不仅在网上看到某人博客的时候要得看该网站PR值、挣钱模式、反向链接之类的;还会在网络之外拿到某人
- IIS(InternetInformationServer)作为当今流行的Web服务器之一,提供了强大的Internet和Intranet服