Liunx 应用程序开发——GCC

来源:互联网 发布:天津空港菜鸟网络 编辑:程序博客网 时间:2024/04/30 09:50

Liunx 应用程序开发—GCC

一、GCC的介绍:

在 Linux 平台上,最流行的编译系统是 GCC(GNU Compile Collection)。GCC 也是 GNU发布的最著名的软件之一。GCC 的功能非常强大,主要体现在两方面。
1) GCC 可以为 x86、ARM、MIPS 等不同体系结构的硬件平台编译程序。
2) GCC 可以编译 C、C++、Pascal、Java 等数十种高级语言。
GCC 的这两项特性对嵌入式应用开发及其重要。此外,GCC 的编译效率也是非常高的,一般要高出其他编译系统 20%到 30%左右。所以在嵌入式 Linux 开发领域,使用的基本上就是 GCC 编译系统。

二、GCC的用法:

gcc 命令的使用格式为:gcc [ 选项 ] [ 文件名 ] [ 选项 ] [文件名]

gcc 命令拥有数量庞大的编译选项,按类型可以把选项分为以下几大类。

1.总体选项:用于控制编译的整个流程。

常用选项:-o  file  :输出目标文件 file

    -E:对源文件进行预处理,展开头文件
    -S:对源文件进行编译,语法检查
    -C:对源文件进行汇编,变为CPU可识别的二进制文件
    -v:显示编译阶段的命令

2.工作流程:

在 C 程序的编译过程中,依次要进行预处理、编译、汇编、链接四个阶段。

例如:test.c
#include <stdio.h>int main(){printf(“Hello world!\n”);return 0;}

    

预处理阶段: gcc -E test.c -o test.i

由于在 test.c 中使用了头文件 stdio.h,所以 GCC 在编译时首先要把头文件 stdio.h中的内容加载到 test.c 中的
首部。在 shell 中输入命令“gcc -E test.c -o test.i”。其中,参数 E 告诉 gcc 命令只进行预编译,不做其他处理;参数
o 用来指明输出的文件名为 test.i。命令运行完毕后就会产生一个名为 test.i 的文件。如下所示:

[root@localhost home]#gcc -E test.c -o test.i[root@localhost home]#lstest.c test.i

test.i 文件的代码有一百多行,如下所示的是 test.i 文件的最后部分代码。

extern char *ctermid (char *__s) __attribute__ ((__nothrow__));72# 820 "/usr/include/stdio.h" 3 4extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__));extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__)) ;extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__));# 850 "/usr/include/stdio.h" 3 4# 2 "test.c" 2int main(){printf(“Hello world!\n”);return 0;}


②. 编译阶段:gcc -S tesc.i -o test.s

编译阶段是整个编译过程中最复杂的一个阶段。

1) 步骤 1 称为词法分析,主要负责检查关键字、标识符等是否正确。
2) 步骤 2 称为语法分析,主要负责检查程序中语句的语法是否正确。
3) 步骤 3 称为语义分析,主要负责检查程序中语句的逻辑意义是否正确。
在 shell 中输入命令“gcc -S test.i -o test.s”。其中,参数 S 告诉 gcc 命令只进行编译,不做其他处理。命令运行

后就会产生一个名为 test.s 的汇编文件。如下所示:

[root@localhost home]#gcc -S test.i -o test.s[root@localhost home]#lstest.c test.i test.s

     如下所示的是 test.s 的代码。 
.file  "test.c".section .rodata.LC0:.string "Hello world!".text.globl main.type  main, @functionmain:leal 4(%esp), %ecx73andl $-16, %esppushl  -4(%ecx)pushl  %ebpmovl %esp, %ebppushl  %ecxsubl $4, %espmovl $.LC0, (%esp)call putsmovl $0, %eaxaddl $4, %esppopl %ecxpopl %ebpleal -4(%ecx), %espret.size  main, .-main.ident  "GCC: (GNU) 4.2.1".section .note.GNU-stack,"",@progbits

③汇编阶段;gcc -c test.s -o test.o

汇编阶段的任务是把汇编程序翻译成 CPU 可以识别的二进制文件,该文件又称为目标文件。
在 shell 中输入命令“gcc -c test.s -o test.o”,其中,参数 c 告诉 gcc 命令只进行汇编,不做其他处理。命令运行完毕后就会产生一个名为 test.o 的目标文件。如下所示
[root@localhost home]#gcc -c test.s -o test.o[root@localhost home]#lstest.c test.i test.o test.s

在 Windows 系统中,目标文件的后缀是 obj。

④链接阶段:gcc test.o -o test

目标文件虽然已经可以被 CPU 直接识别,但是单个目标文件一般是无法运行的。原因在于一个程序往往是由多个
源文件组成的,每个源文件只对应一个目标文件。也许有人会问,test 程序不就只有一个源文件 test.c 吗,为什么也不
能直接运行呢?原因是 test.c 使用了 stdio.h 对应的库函数,所以必须要把 test.o 文件和函数库文件链接在一起才能运
行。
链接阶段的任务就是把程序中所有的目标文件和所需的库文件都链接在一起,最终生成一个可以直接运行的文件,
称为可执行文件。
在 shell 中输入命令“gcc test.o -o test”,运行完毕后就会产生一个名为 test 的可执行文件。输入命令“./test”执行该
文件,就可以得到 test 文件的运行结果“Hello world!”。 如下所示:
[root@localhost home]#gcc test.o -o test[root@localhost home]#./testHello world!




原创粉丝点击