Linux下使用g++编译C++方法

发布时间 - 2018-03-26 00:00:00    点击率:

本文主要和大家分享在linux环境中用g++编译c++的方法以及相关实例代码分享,有兴趣的朋友学习下。希望能帮助到大家。

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

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


/* helloworld.cpp */
#include 
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 
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 
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  # mysql  # Object  # include  # 字符串  # 预处理器  # 对象  # 数据库  # ar  # 可执行  # 头文件  # 可执行文件  # 库中  # 是一个  # 源代码  # 汇编语言  # 命令行  # 多个  # 将其 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 怎样使用JSON进行数据交换_它有什么限制  googleplay官方入口在哪里_Google Play官方商店快速入口指南  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  音乐网站服务器如何优化API响应速度?  Laravel如何实现API版本控制_Laravel API版本化路由设计策略  百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏  Laravel如何清理系统缓存命令_Laravel清除路由配置及视图缓存的方法【总结】  如何正确选择百度移动适配建站域名?  如何用AI帮你把自己的生活经历写成一个有趣的故事?  Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】  家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?  为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】  Win11怎样安装网易有道词典_Win11安装词典教程【步骤】  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南  如何用虚拟主机快速搭建网站?详细步骤解析  javascript如何操作浏览器历史记录_怎样实现无刷新导航  如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体  微信推文制作网站有哪些,怎么做微信推文,急?  浅谈Javascript中的Label语句  悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤  微信小程序制作网站有哪些,微信小程序需要做网站吗?  网站页面设计需要考虑到这些问题  如何在 Pandas 中基于一列条件计算另一列的分组均值  php打包exe后无法访问网络共享_共享权限设置方法【教程】  JavaScript中的标签模板是什么_它如何扩展字符串功能  如何用低价快速搭建高质量网站?  如何挑选高效建站主机与优质域名?  Python自动化办公教程_ExcelWordPDF批量处理案例  nodejs redis 发布订阅机制封装实现方法及实例代码  ChatGPT常用指令模板大全 新手快速上手的万能Prompt合集  韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐  北京企业网站设计制作公司,北京铁路集团官方网站?  Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程  Laravel storage目录权限问题_Laravel文件写入权限设置  laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法  Linux后台任务运行方法_nohup与&使用技巧【技巧】  Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑  如何用PHP快速搭建CMS系统?  大连 网站制作,大连天途有线官网?  Python结构化数据采集_字段抽取解析【教程】  EditPlus中的正则表达式实战(5)  微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】  如何在香港服务器上快速搭建免备案网站?  制作公司内部网站有哪些,内网如何建网站?  网站制作报价单模板图片,小松挖机官方网站报价?  详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)  javascript日期怎么处理_如何格式化输出  Laravel如何与Inertia.js和Vue/React构建现代单页应用  Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】