在Linux环境下,我们通常用gcc将C代码编译成可执行文件,如下就是一个简单的例子:
代码文件:hello.c
#include <stdlib.h>
#include <stdio.h>
void main(void)
{
printf("hello world!\r\n");
}
可以通过如下指令来编译出一个可执行文件:
gcc hello.c
执行完该命令后,就会得到一个a.out的可执行文件。
编译的过程
前面的例子只是简单的介绍了一下gcc的使用方法,熟悉c编程的朋友就会知道,该步骤其实包含了预处理-->编译-->汇编-->链接四步,这四步分别实现的功能如下:
由此可以看出,每一个阶段的输出其实就是下一个阶段的输入,用gcc是可以单独执行这四步的:
gcc -E hello.c -o hello.i
gcc -S hello.i -o hello.s
gcc -c hello.s -o hello.o
gcc hello.o -o hello.exe
实际上,由于这四个步骤太过于复杂,往往可以像我上面那样全部集中到一个命令中来执行:
gcc hello.c -o hello.exe
这里我加了一个-o参数来指定输出名称,而不是默认的a.out。
如果有多个文件,则可以通过如下方式全部集中起来。
gcc -o test first.c second.c third.c
这个全生成的方式虽然非常简单,但是存在的一个问题就是:当项目较大时,如果只改了一个文件,仍需要重新编译索引文件。
为了解决这个问题,我们往往把这个编译过程拆分成两步:
gcc –c first.c
gcc –c second.c
gcc –c third.c
gcc -o test first.o second.o third.o
这样,当third.c文件发生改变时,只需要重新编译third.c和链接即可,这样就省去了未变化文件的编译时间,也就是我们通常所说的增量编译。
gcc –c third.c
gcc -o test first.o second.o third.o
从上面的使用方法中我们也可以看到:
由于程序员往往并不关心前面两个几个阶段生成的输出文件,通常我们也把预处理、编译、汇编三个阶段合并在一起,统称为编译,输入.c,生成.o。
常用参数:
前面其实已经演示过-E、–S、–c、–o等几个参数的用法,其中-E及-S很少会用到,-c用于编译生成.o文件,-o用于指定输出文件名称。除了这几个生成控制的参数外,还有许多参数设置,这里主要介绍一下几个常用的:
包含头文件和库:
宏定义:
调试和可执行文件形式:
告警选项:
gcc和g++
除了gcc编译器外,还有另外一个编译器g++,很多人往往搞不清楚这两个编译器的区别,很多人望文生义的认为gcc只能编c代码,g++只能编c++代码。实际上这两个编译器的主要区别如下:
关于它们的区别的更多信息,可以参考这个文章:http://ldzyz007.iteye.com/blog/865080
为了使用简单,可以制定如下规则:对c项目使用gcc,对c++项目使用g++。估计当时设计这个名字的意图也是如此吧。