GCC编译流程

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

1.预处理阶段

[ht@localhost hello]$ gcc -E hello.c -o hello.i
Gcc进行预处理,把“stdio.h”的内容插入到hello.i文件中。

2.编译阶段

[ht@localhost hello]$ gcc -S hello.i -o hello.s

.file    "hello.c"
    .section    .rodata
.LC0:
    .string    "Hello world !"
    .text
    .globl    main
    .type    main, @function
main:
.LFB0:
    .cfi_startproc
    leal    4(%esp), %ecx
    .cfi_def_cfa 1, 0
    andl    $-16, %esp
    pushl    -4(%ecx)
    pushl    %ebp
    .cfi_escape 0x10,0x5,0x2,0x75,0
    movl    %esp, %ebp
    pushl    %ecx
    .cfi_escape 0xf,0x3,0x75,0x7c,0x6
    subl    $4, %esp
    subl    $12, %esp
    pushl    $.LC0
    call    puts
    addl    $16, %esp
    movl    $0, %eax
    movl    -4(%ebp), %ecx
    .cfi_def_cfa 1, 0
    leave
    .cfi_restore 5
    leal    -4(%ecx), %esp
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE0:
    .size    main, .-main
    .ident    "GCC: (GNU) 4.9.2 20141101 (Red Hat 4.9.2-1)"
    .section    .note.GNU-stack,"",@progbits

3.汇编阶段

[ht@localhost hello]$ gcc -c hello.s -o hello.o
4.链接阶段

[ht@localhost hello]$ gcc hello.o -o hello
[ht@localhost hello]$ ls
hello  hello.c  hello.i  hello.o  hello.s
[ht@localhost hello]$ ./hello
Hello world !
系统把这些函数实现都被做到名为libc.so.6的库文件中去了,在没有特别指定时,Gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到libc.so.6库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。函数库一般分为静态库和动态库两种。静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”。动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的libc.so.6就是动态库。Gcc在编译时默认使用动态库。

 

比如 -I dir

/*hello.h*/
#ifndef _HELLO_H
#define _HELLO_H
#include <stdio.h>

#endif
/*hello.c*/
#include<hello.h>
int main()
{
        printf("Hello world !\n");
        return 0;
}

[ht@localhost hello]$ gcc hello.c -I /home/ht/MYCODE/hello/ -o hello

在include语句中,“<>”表示在标准路径中搜索头文件,““””表示在本目录中搜索。故在上例中,可把hello.c的“#include<hello.h>”改为“#include “hello.h””,就不需要加上“-I”选项了。

 

posted @ 2015-02-27 16:20  ht-beyond  阅读(295)  评论(0编辑  收藏  举报