转自http://wiki.ubuntu.org.cn/index.php?title=Compiling_Cpp&variant=zh-hans

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

.a 静态库 (archive)
.C
.c
.cc
.cp
.cpp
.cxx
.c++
C++源代码(需要编译预处理)
.h C或者C++源代码头文件
.ii C++源代码(不需编译预处理)
.o 对象文件
.s 汇编语言代码
.so 动态库
<none> 标准C++系统头文件

[编辑]单个源文件生成可执行程序

下面是一个保存在文件 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

Compiling Cpp相关推荐

  1. Compiling Cpp(zz)

    zz: http://wiki.ubuntu.org.cn/Compiling_Cpp C++ 编程中相关文件后缀 .a 静态库 (archive) .C .c .cc .cp .cpp .cxx . ...

  2. Linux下使用g++编译C++程序——Compiling Cpp

    g++和gcc:准确的说都是GNU(组织)的一个编译器 区别:后缀为.c的文件gcc把它当做c程序,g++当做c++程序.后缀为c++的两者都当做c++程序.对于cpp程序,无论gcc或者是g++编译 ...

  3. UNREAL ENGINE 4.13 正式发布!

    这次的版本带来了数百个虚幻引擎 4 的更新,包括来自 GitHub 的社区成员们提交的 145 个改进!感谢所有为虚幻引擎 4 添砖加瓦贡献的人们: alk3ovation, Allegorithmi ...

  4. Makefile:.d依赖文件

    https://blog.csdn.net/huao798480517/article/details/8691018 1. 在Makefile中,我们的依赖关系可能会需要包含一系列的头文件,比如,如 ...

  5. Compiling: main.cpp /bin/sh: g++: not found

    Kbuntu用codeblocks编写C程序的时候,编译报错如下: Compiling: main.cpp /bin/sh: g++: not found 解决方法: sudo apt-get ins ...

  6. ninja Compiling the C compiler identification source file CMakeCCompilerId.c failed

    Compiling the C compiler identification source file "CMakeCCompilerId.c" failed 同时,控制台也报错: ...

  7. Compiling Fortran

    Compiling Fortran 目录 [隐藏] 1 写在前面 2 Fortran 编程中相关文件后缀 3 单个源文件生成可执行程序 4 多个源文件生成可执行程序 5 生成汇编代码 6 编译预处理 ...

  8. 把cpp编译为so_基于VSCode和CMake进行C/C++开发第三讲GCC编译器

    3.0 本讲目录 本系列视频,B站首发,up主: xiaobing1016 前言: GCC 编译器支持编译 Go.Objective-C,Objective-C ++,Fortran,Ada,D 和 ...

  9. Compiling a Compiler

    Compiling a Compiler 作者: lihuawei, 可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息. | <script src="http://w ...

最新文章

  1. 你的模型刚不刚?谷歌提出“刚度”概念,探索神经网络泛化新视角
  2. 现场|除了谷歌AI中国中心成立的重磅消息,谷歌开发者大会现场还有这些
  3. SQLite中SELECT基本形式
  4. python导入excel表格-Python 将Excel表格数据导入MySQL数据库
  5. python中的栈结构_对Python列表进行封装和二次开发实现自定义栈结构
  6. python遍历指定文件夹的所有文件_python 统计指定文件夹下所有的文件数量,BFS方式...
  7. 一文了解自然语言生成演变史!
  8. 【MatConvnet速成】MatConvnet图像分类从模型自定义到测试
  9. 织梦ajax表单提交参数错误,【织梦二次开发】织梦jquery+ajax方式提交自定义表单...
  10. 多线程原理分析面试题理解
  11. 最大数输出(信息学奥赛一本通-T1053)
  12. 词根 sent/sens
  13. php 中 date转换为字符串,PHP 时间与字符串的相互转化
  14. 【深度学习笔记】深度学习用于图片的分类和检测总结
  15. docker下beego开发环境搭建
  16. 小马哥讲Spring核心编程思想 - 第二章 重新认识IoC
  17. ubuntu如何更改IP地址
  18. 电脑重装Windows操作系统的几种方法
  19. 卡内基梅隆计算机金融,大神offer|恭喜四位再来人学员斩获卡内基梅隆大学-计算金融硕士...
  20. 我为什么从阿里巴巴集团离职?

热门文章

  1. sql优化之查询优化器
  2. 从抓包砍到接口测试,五分钟看完全过程解析,还说你不会测试?
  3. 使用gitlab ci构建IOS包并发送通知消息到企业微信
  4. 小米集团高管变动:崔宝秋因个人原因离职
  5. pyQT5 学习使用 笔记 六 pyQt5+opencv 显示海康GIGE相机动态视频流
  6. php 直播流,ngnix开发(五)将rtmp直播流转换成hls直播流
  7. 北邮网研院宿舍_北邮研究生宿舍条件(北邮研究生宿舍图片)
  8. JIS-CTF 靶机渗透
  9. Testpoint设置的疑问
  10. matlab 中lsim的用法,lsim的用法