转:http://blog.csdn.net/liujiayu2/article/details/49864381

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

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

[cpp] view plaincopy print?
  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,向标准输出写入一个简单的字符串。该代码可用以下命令编译为可执行文件: 
$  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 的头文件;它包含一个仅含有一个函数的类的定义:

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

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

[cpp] view plaincopy print?
  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 类的程序:

[cpp] view plaincopy print?
  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. }

下面这条命令将上述两个源码文件编译链接成一个单一的可执行程序: 
$ 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 的定义:

[cpp] view plaincopy print?
  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 library\n";
  15. }
  16. void sayString(void);
  17. };

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

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

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

[cpp] view plaincopy print?
  1. /* sayhello.cpp */
  2. #include "say.h"
  3. void sayhello()
  4. {
  5. std::cout << "hello from a static library\n";
  6. }

下面的命令序列将源码文件编译成对象文件,命令 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 中的代码:

[cpp] view plaincopy print?
  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. }

该程序可以下面的命令来编译和链接: 
$ g++ saymain.cpp libsay.a -o saymain
程序运行时,产生以下输出: 
hello from a static library
howdy from a static library
Library instance of SayLocal instance of Say

转载于:https://www.cnblogs.com/studyskill/p/8335833.html

转:gcc编译C++程序相关推荐

  1. linux如何用gcc编译c程序,Ubuntu之如何使用gcc编译C语言程序

    在大学里面大家都用过VC6.0来进行编程.VC6.0属于集成开发环境,一份代码从文本变成可执行的程序只需要在其中点击几个按钮就行了,加之老师也只教过我们如何操作,并未介绍C语言的执行过程.上一篇曾提到 ...

  2. win7 上面 gcc 编译的程序 a exe 运行的时候报错 a exe 已停止工作, 异常代码 c0000005

    win7 上面 gcc 编译的程序 a.exe 运行的时候报错 a.exe 已停止工作, 异常代码:c0000005: 原因分析: 一开始我以为是我的代码的问题,后来查询了这个错误码发现原来是兼容性的 ...

  3. c语言conflicting types,gcc编译C程序出现”error conflicting types for function”编译错误的分析解决...

    今天使用gcc编译C语言程序时出现 "error conflicting types for function" 编译错误,这个错误的原因是什么?如何解决?以下看正文的讲解. 在使 ...

  4. 使用gcc编译c语言程序,用GCC编译C ++程序

    在这里,我们将看到如何使用GCC(GNU C编译器)编译C ++程序.让我们考虑一下,我们要编译这个程序. 示例#include using namespace std; main() { cout  ...

  5. linux gcc编译C程序 分享

    一个c语言程序从源文件到生成可执行文件,编译器需要共经历4个步骤: 1) 预处理:把c文件中预处理命令扫描处理完毕,即对源代码文件中的文件包含(#include).预编译语句(如宏定义#define等 ...

  6. 使用gcc编译和链接C语言程序,用GCC编译链接程序--编译链接器GCC常用功能(菜鸟级)...

    转载自:http://daimajishu.iteye.com/blog/1089740 对gcc认识的一篇文章,就转载了,截取了自己感兴趣部分. 一,GCC编译器简介 虽然我们称Gcc是C语言的编译 ...

  7. GCC 编译 C++ 程序分步骤流程(预处理 gcc -E、编译 gcc -S、汇编 gcc -c 和链接 gcc 以及 gcc -o 选项)

    C 或者 C++ 程序从源代码生成可执行程序的过程,需经历 4 个过程,分别是预处理.编译.汇编和链接. 同样,使用 GCC 编译器编译 C 或者 C++ 程序,也必须要经历这 4 个过程.但考虑在实 ...

  8. gcc编译C++程序

     单个源文件生成可执行程序 下面是一个保存在文件 helloworld.cpp 中一个简单的 C++ 程序的代码:  /* helloworld.cpp */ #include <iostr ...

  9. C++:GCC编译:GCC编译C++程序分步流程

    C或者C++程序从源代码生成可执行程序的过程,需要经历4个过程分别是:预处理,编译,汇编,链接. 但考虑实际使用过程中,用户可能并不关心程序的执行结果,只是想快速得到最终的可执行程序,因此gcc和gc ...

最新文章

  1. Android StateFlow详解
  2. boost::callable_traits的is_lvalue_reference_member的测试程序
  3. scrapy配合selenium爬取需要反复操作同一个动态页面的方法,解决点击“下一页”但是URL相同的网站
  4. Linux下eclipse编译C/C++程序遇到 undefined reference to `pthread_create'的异常解决办法
  5. 生成逼真3D人偶,居然不用3D形状建模,还能学会你的舞步 | 三星CVPR Oral
  6. java swing html_Swing中如何使用HTML按钮
  7. jq数组清空_JQuery 数组获取和删除元素
  8. 编译原理(第3版)第1章引论课后题答案
  9. Java静态代理、动态代理
  10. plm系统服务器,SIPM/PLM
  11. Collection NSArrayM was mutated while being enumerated
  12. 树的中序遍历(递归,迭代,莫里斯)
  13. 论文写作笔记7 大纲outline写作方法
  14. 自己动手刷原生android系统
  15. jquery实现字数限制,超过部分...代替,后缀点击展开,点击后展开全文
  16. 追寻绿色世界、草木清香
  17. php 1 second,php中的会话机制(1)
  18. 感谢折磨你的人[三]
  19. Radius协议讲解
  20. 海马汽车经销商管理系统技术解析(七)预约失败处理

热门文章

  1. rabbitmq充分利mysql_牛逼哄哄的 RabbitMQ 到底有啥用?
  2. echart单击后获取横坐标值_Excel综合应用(1): 批量打印格式化后的表格
  3. socket通信基础知识
  4. php查看mysql最近执行过的sql_PHP获取MySQL执行sql语句的查询时间
  5. CDM CDP及传统备份技术对比
  6. 宿迁市烟草专卖局(公司)系统信息系统运行维护管理办法(试行)
  7. vSphere 7融合Kubernetes,构建现代化应用的平台
  8. 云服务器 ECS > 网络 > 经典网络迁移至专有网络
  9. 在sql server 发生未指定的错误_一条sql查询是怎么执行的?
  10. turtle填充随机颜色同心圆