CC/G++ 学习笔记
CC/G++ 学习笔记
本文是《An introduction to GCC》的学习笔记,记录使用GCC/G++主要的实用技巧,本文讲述的知识基本上摘自本书,附带自己的一些体验。如果想详细查看本书,请戳这里。
一、gcc
1. 命令 $ gcc test.c -o test
将test.c 命令编译成test可执行程序。-o 命令制定输出文件名。
没有任何其他的参数即默认编译成可执行程序,输入命令 $ ./test 即可执行。gcc 实际上是分成四步:预处理、编译、汇编、链接。
- $ gcc -E hello.c -o hello.i 只执行预处理
- $ gcc -S hello.c -o hello.s 执行预处理和编译
- $ gcc -c hello.c -o hello.o 执行预处理、编译、连接
- $ gcc hello -o hello 执行四个步骤,得到excutable file
关于这四步的详细解释先给出这些,有大个体的认识,如果想详细了解,请往下看,或者阅读《An introduction to GCC》
2. 如果有错误
如果程序出现错误,gcc则会停止编译,不会最终生成文件,并提示错误信息。错误信息提示按如下格式:
filename: line-number : error message 。
编译器区分报错信息和警告信息,不能成功编译的是报错信息,指示可能的错误的是警告(但并不停止程序的编译,如果希望警告则停止也有方法,使用-Werror编译选项即可)。
通过提示的编译错误提示可以较为方便的找到错误。
3. 如果希望编译多个文件
如果希望编译多个文件,只要程序布局正确,也很简单,直接罗列出所有的.c文件,最后生成可执行文件即可。.h 头文件不用显示写出,因为在编译.c文件的时候会自动编译关联的.h文件。如:
$ gcc file1.c file2.c -o file。
如果程序很大,包含多个源文件,但是只修改了其中的一个或两个文件怎么办?难道需要重新编译所有的吗?如果源程序很大时,这么做是非常低效的。因此,一个方法是采用分步独立编译的方法。参考上面说明的四步编译,
- 先把各个源文件编译分别成目标文件
- 再将目标文件进行链接成可执行文件
- 当修改其中一部分源文件时,只需要将修改过的源文件编译成目标文件
- 再将所有的目标文件链接成可执行文件即可。
但是,这样其实也非常低效,make 命令很好的解决这个问题。虽然make非常强大,在编写大型软件时强烈建议使用make,但make不在本文的讨论范围。
二、编译选项(重点)
对于gcc使用者来说,最终要的就是这些编译选项了。编译选项非常多,这里只总结较为经常使用的一些命令。
- -o 指定生成的可执行文件的名字(常用,不用例子了吧)
- -Dmacro 定义指定的宏,使他能够通过源码中的 #ifdef 进行检验(不常用,就不举例了,详细请阅读《gccintro》)
- -LDIRNAME 将DIRNAME(路径名) 加入到库文件搜索的路径中
- -g 在可执行文件中包含标准调试信息(用gdb调试时经常使用,重要)
- -lDIRNAME 将DIRNAME(路径名)加入到头文件搜索路径中
- -llibrary 提示连接程序在创建最终可执行文件时包含指定的库(不熟悉)
- -O, -O2, -O3 将优化状态打开,该选项不能与-g选项联合使用
- -E, -S, -c 管理编译过程。
- -Wall 打开所有最常用到的编译警告,即如果程序中有警告,则提示。(重要,有时候能避免错误,因此强烈建议每次使用时都加上。)
- -Werror 发生警报时停止编译操作
- -w 禁止所有警报
- -static 对库文件进行静态连接
- -ggdb 在可执行文件中包含只有gdb才能识别的大量调试信息
三、预处理
1. 预处理: 展开源文件中的宏。(宏就不解释了)
2. 宏定义
有三种方法可以定义宏:
- 在源程序中利用 # define MAX 100 的方式
- 在gcc命令中利用选项 -Dmacro ,macro即为宏如:

// macro.c
#include <stdio.h>
int main (void)
{
#ifdef TEST
printf ("Test mode\n");
#endif
printf ("Running...\n");
return 0;
}

执行命令:$ gcc -Wall -DTEST macro.c -o macro,得到的结果是: Test mode
- 有些宏是由编译器自动定义的----这些宏会用到由双下划线(__)开始的保留的名字空间。
3. 预处理源文件
命令选项: -E。这个选项将源文件(.c)预处理为 .i 结尾的文件。
// test.c
# define TEST "hello world"
const char str[] = TEST
利用命令 $ gcc -E test.c -o test.i ,执行后得到 test.i 即为预处理后的文件。
// test.i
# define TEST "hello world"
const char str[] = "hello world"
从上面两个文件对比,可以看到,已经进行了宏替换
四、带调试信息选项
1. 如果需要调试,使用gdb工具,不过在使用前必须在使用-g选项
2. 使用core文件获取错误信息。不常用,详细阅读**
五、编译优化(暂略)
六、编译相关工具
1. 用 GNU 归档工具 ar 创建静态库
2. 使用性能剖析器 gprof
GNU 性能剖析器 gprof 是衡量程序性能的有用工具----它记录每个函数调用的次数和每个函数每次调用所花的时间。函数在运行期所花费的大部分时间可以很容易地由 gprof 标识出来。加速程序运行的努力应该首先被放在那些在总体运行时间中“称王称霸”的函数。
为了剖析性能,该程序必须带“-pg”选项来编译和链接:
$ gcc –Wall –c –pg collatz.c
$ gcc –Wall –pg collatz.o
这就生成了一个会产生剖析数据的可执行文件,其包含有记录每个函数所花时间的额外指令。如果程序有多个源代码文件,则编译每个源文件时都要带上“-pg”选项,同样在把多个对象文件链接以生成最后的可执行文件时也要如法炮制(象上面展示的) 。忘记在链接时带“-pg”选项常见错误,在剖析性能时不会生成任何有用的信息。可执行文件只有通过运行才能生成剖析数据:
$ ./a.out
(显示程序的正常输出)
运行生成的可测量的可执行文件后,剖析数据被悄无声息地记录到当前目录下的“gmon.out”文件中。以可执行文件名作为参数运行 gprof 就可以分析这些数据:
$ gprof $ ./a.out
(显示程序的各函数耗费时间)
3. 用 gcov 进行代码覆盖测试(貌似很好使)
GNU 代码覆盖测试工具 gcov 分析在程序运行期间每一行代码执行的次数。这就使找到没有被用到的代码区域或没有被测试到的代码成为可能。
七、编译过程
1. 预处理:将宏定义展开
2. 编译:从源代码到适合处理器兼容的汇编代码
3. 汇编:将汇编程序编译成目标代码(机器码)
4. 链接:将生成的目标代码利用ld工具连接成一个可执行文件
八、G++
G++ 和 GCC的使用情况大致一样,不再特别说明。
CC/G++ 学习笔记的更多相关文章
- GCC/G++ 学习笔记
本文是<An introduction to GCC>的学习笔记,记录使用GCC/G++主要的实用技巧,本文讲述的知识基本上摘自本书,附带自己的一些体验.如果想详细查看本书,请戳这里. 一 ...
- g++ 学习笔记
gcc and g++分别是GNU的c & c++编译器.gcc/g++在执行编译的时候一般有下面4步: 1 预处理,生成.i的文件. 命令如下:g++ -E test.cpp 此命令只进行 ...
- cc代码学习笔记1
#define #define INT32 int #define INT8 char #define CHAR char #define SSHORT signed short #define IN ...
- cocos2d-html5学习笔记(六)--alpha2中cc.Sequence.create中的bug
cocos2d-html5学习笔记(六)--alpha2中cc.Sequence.create中的bug http://blog.csdn.net/allenice1/article/details/ ...
- Vue.js学习笔记(2)vue-router
vue中vue-router的使用:
- RAC学习笔记
RAC学习笔记 ReactiveCocoa(简称为RAC),是由Github开源的一个应用于iOS和OS开发的新框架,Cocoa是苹果整套框架的简称,因此很多苹果框架喜欢以Cocoa结尾. 在学习Re ...
- Makefile的学习笔记
Makefile的学习笔记 标签: makefilewildcard扩展includeshellfile 2012-01-03 00:07 9586人阅读 评论(2) 收藏 举报 分类: Linux ...
- android cocos2d-x for Android安装和学习笔记(请用adt-bundle21.1或以上导入)
引用:http://weimingtom.iteye.com/blog/1483566 (20121108)注意:这篇文章用cdt编译ndk工程的内容已过时(现在可以用adt-bundle,避免配置繁 ...
- DBus学习笔记
摘要:DBus作为一个轻量级的IPC被越来越多的平台接受,在MeeGo中DBus也是主要的进程间通信方式,这个笔记将从基本概念开始记录笔者学习DBus的过程 [1] DBus学习笔记一:DBus学习的 ...
随机推荐
- OS和android游戏纹理优化和内存优化(cocos2d-x)
注:原文地址不详! 1.2d游戏最占内存的无疑是图片资源. 2.cocos2d-x不同平台读取纹理的机制不同. ios以下使用CGImage,android和windows下是直接调用png库.我測试 ...
- iOS8开发~UI布局(二)storyboard中autolayout和size class的使用具体解释
一.概要:前一篇初步的描写叙述了size class的概念,那么实际中怎样使用呢,以下两个问题是我们一定会遇到的: 1.Xcode6中添加了size class,在storyboard中怎样使用? 2 ...
- Swift中文教程(三)--流程控制
原文:Swift中文教程(三)--流程控制 Swift用if和switch编写条件控制语句,用for-in,for,while和do-while编写循环.条件控制语句和循环语句中,小括号是可选的,但花 ...
- 教你一步一步部署.net免费空间OpenShift系列之一------帐号注册和验证
前几天有博友发布了一篇文章<一键部署mono 免费空间支持ASP.NET MVC 再也不担心伙食费换空间了>,支持MVC3和域名绑定,觉得不错,于是自己实践了一下,发现自己实际遇到的问题真 ...
- bootstrap-wysiwyg 结合 base64 解码 .net bbs 图片操作类 (三) 图片裁剪
官方的例子 是 长方形的. 我这里 用于 正方形的头像 所以 做如下 修改 #preview-pane .preview-container { width: 73px; height: 73px ...
- javascript常用知识点集
javascript常用知识点集 目录结构 一.jquery源码中常见知识点 二.javascript中原型链常见的知识点 三.常用的方法集知识点 一.jquery源码中常见的知识点 1.string ...
- PHP 使用用户自定义的比较函数对数组中的值进行排序
原文:PHP 使用用户自定义的比较函数对数组中的值进行排序 usort (PHP 4, PHP 5) usort — 使用用户自定义的比较函数对数组中的值进行排序 说明 bool ...
- MySQL 一般查询日志(General Query Log)
与大多数关系型数据库,日志文件是MySQL数据库的一个重要组成部分.MySQL有几种不同的日志文件,通常包括错误日志文件,二进制日志,通用日志.慢查询日志,等等. 这些日志能够帮助我们定位mysqld ...
- 一个意想不到的CDO.Message 错误
原文:一个意想不到的CDO.Message 错误 几个月之前,写了一个服务从MSMQ取消息发群发邮件的程序,一直也没时间测试,今日一试,出现发送邮件时报错,异常情况如下: "Syst ...
- Wowza流媒体Live直播和VOD点播配置实战
Wowza是当今可以说最流行的流媒体服务器之一,近来因为需要搭建相应的服务器,但又不想用camera等作真实的直播,所以想办法用媒体文件转换成直播流再提供给Wowza进行直播.这里把该设置步骤以及设计 ...