通常的开发环境都是流行的集成开发环境(IDE)。这样的IDE一般都是将编译和链接的过程一步完成,通常将这种编译和链接合并到一起的过程称为构建

2.1被隐藏了的过程

#include<stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}

上面代码文件名为:hello.c,编译代码的过程可以分解为4个步骤:

  • 预处理
  • 编译
  • 汇编
  • 链接

2.1.1 预编译

源代码文件hello.c和相关头文件,如stdio.h等被预编译器cpp预编译成一个.i文件。
对于C++程序来说,源代码文件的扩展名可能是.cpp或.cxx,头文件的扩展名可能是.hpp,而编译后的文件扩展名是.ii。

如下图,我这里使用的是Ubuntu的系统:
这里编译上面的程序

程序员的自我修养二编译和链接

这里可以看到生成了一个.i的文件,下面打开它:(只截取了文件开头和结尾)

程序员的自我修养二编译和链接

程序员的自我修养二编译和链接

预编译过程主要处理规则如下:

  • 将所有的”#define”删除,并且展开所有宏定义。
  • 处理所有条件预编译指令,比如”#if”
  • 处理”#include”预编译指令,将包含的文件插入到该预编译指令的位置
  • 删除所有注释”//”和”/**/”
  • 添加行号和文件
  • 保留所有的#pragme编译器指令,因为编译器需要使用它们

经过预编译后的.i文件不包含任何宏定义,因为所有的宏已经被展开。

2.1.2 编译

编译过程就是把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后生产相应的汇编代码文件。现在版本的GCC把预编译和编译两个步骤合并成一个步骤,使用叫做ccl的程序来完成这两个步骤。

下面我们把预处理完的文件进行编译:

程序员的自我修养二编译和链接

打开它看看

程序员的自我修养二编译和链接

    .file    "hello.c"
    .section    .rodata
.LC0:
    .string    "Hello World"
    .text
    .globl    main
    .type    main, @function
main:
.LFB0:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $.LC0, %edi
    call    puts
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size    main, .-main
    .ident    "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609"
    .section    .note.GNU-stack,"",@progbits
View Code

相关文章: