gcc命令

GCC说明

GCC 最初是 GNU C Compiler 的缩写,也就是最初是 c 编译器,后来演变成了 GNU Compiler Collection 的缩写,也就是成了一个编译器的集合。GCC 可以编译 c 、c++、、objective-c、objective-c++、java、pascal、ada 等语言,不过很多时候 me 们关心的是如何编译 c 和 c++。linux 主要是用 c 写的,其上的各种实用工具(比如各种命令)一般也是 c 写成的;而 GCC 最初也是用 c 写的,后来改用了 c++。

通常用 gcc 命令来编译 c 文件,用 g++ 命令来编译 c++ 文件。不过也可以使用 gcc 来编译 c++ 文件(链接 libstdc++ 库而不是 glibc 库)。下面主要是通过 gcc 命令来说明编译,g++ 的基本是一样的。

编译过程

假设现在有一个 hello.c 文件:

  1. #include <stdio.h>
  2. int main()
  3. {
  4.     printf("hello,world\n");
  5.    
  6.     return 0;
  7. }

me 们可以使用命令 $ gcc hello.c ($ 是命令提示符,不是命令的一部分 !!) 来编译该文件,然后生成 a.out 可执行文件。可以通过 $ ./a.out 来执行该文件。

hello.c 是文本文件,编译后生成的 a.out 是二进制(可执行)文件,其中的编译过程实际上细分成四步 : 预处理、编译、汇编、链接,每一步都有专门的工具进行处理,过程是:

hello.c === cpp ===> hello.i === cc1 ===> hello.s === as ===> hello.o === ld ===> a.out

更详细的处理过程如下所述:

  1. 预处理 (cpp) : 将文件中的预处理指令,比如 #include 和 #define 进行展开。#include 包含的文件会插入该指令处,#define 会将文件中的宏替换成对应的字符串;生成的文件后缀一般是 .i ,也就是 hello.c ==> hello.i ;预处理过后的 hello.i 是文本文件;
  2. 编译 (cc1 或是 cc1plus) :将经过预处理的 .i 文件进行编译,生成汇编代码,此处仍是文本文件;后缀一般是 .s ,也就是 hello.i ==> hello.s ;
  3. 汇编 (as) : 将编译生成的 .s 文件汇编成目标文件,这里已经是二进制文件了;后缀是 .o, 也就是 hello.s ==> hello.o ;
  4. 链接 (ld) : 将目标文件 .o 和库文件 .a 链接生成可执行文件,当然也是二进制文件,没有规定的后缀;默认是 hello.o ==> a.out ;

上面的 cpp 、cc1、 as 和 ld 分别是预处理器、编译器、汇编器和链接器,为 gcc 命令所调用。

GCC 编译选项

部分编译

默认的 $ gcc 是一下子完成上面的四步,me 们可以通过编译选项控制只完成前面的步骤: -E -S -c 分别只进行第一步、第二步和第三步的操作。

  1. $ gcc -E hello.c    # 只进行预处理,也就是完成第一步;
  2. $ gcc -S hello.c/hello.i    # 完成第二步编译,生成 .s 汇编文件;
  3. $ gcc -c hello.c/hello.i/hello.s    # 完成第三步汇编,生成 .o 目标文件;
  4. $ gcc hello.c/hello.i/hello.s/hello.o    # 默认生成可执行文件 a.out;

其他编译选项:

  • -o filename :指定生成文件的名字,比如 -o hello 、-o hello.i 等;
  • -D macro_name=value :设定预处理的宏,比如 -D NDEBUG = 3, =value 部分可有可无(也就是 =3 不是必需的);
  • -Idir :指定不在标准或是系统搜索路径中的 include 文件路径;-Idir 可以覆盖系统标准目录,也就是 -Idir 的优先级别高于系统目录;
  • -Ldir :指定不在标准或是系统搜索路径中的 lib 文件路径;
  • -l library :指定链接的库,比如 -l pthread 线程库;-l 和 library 之间的空格可以省略,比如 -lpthread ;
  • -Wall :显示所有的警告;
  • -O2 :二级优化,可以让程序跑得更快,but 可能调试不方便;
  • -std=标准 :指定语言标准,比如 c++11、gnu99 等;

Tags: 

Article type: 

Comments

控制语言的标准级别

gcc 可以用来编译 c、c++, 而 c 和 c++ 的标准已经有了多个, c 有 c89、 c99 和 c11 三个, c++ 主要有 c++98 和 c++11 两个。 11 就是 2011 年的。 c 语言相对来说比较稳定,大家主要还是在用 1989 年的标准, c++ 现在已经是 2011 了。 c 的稳定可能是因为其已经能满足系统开发的需求了, 而 c++ 则一般推荐使用最新的标准和编译器, 可能是因为 c++ 相对于 c 来说要上层一些。

gcc 可以带不同的编译选项, 也就是按照不同的标准来编译程序。

  • $ gcc -ansi 和 $ gcc -std=c89 是一样的;也就是 c 语言的第一个标准;
  • $ gcc -std=c99 使用 c 的 99 年的标准;
  • $ gcc -std=gnu89 和 $gcc -std=gnu99 是说使用 89、99 的 gnu 扩展;
  • $ g++ -std=c++11 使用 c++ 11 年的标准;

精诚所至,金石为开